I am creating a simple IOS Application will a countdown timer. When I run the app in the simulator the countdown timer doesn't countdown. It simply stays at the current time.
Also any suggestions on making the numbers line up would be nice.
My .h file
// ViewController.h
// ******
//
// Created by ***** on 7/29/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface ViewController : UIViewController {
NSDate *destinationDate;
IBOutlet UILabel *datelabel;
NSTimer *timer;
}
#end
My .m file
//
// ViewController.m
// ******
//
// Created by ******* on 7/29/12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "ViewController.h"
#implementation ViewController
-(void) updateLabel {
NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
int units = NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *components = [calender components:units fromDate:[NSDate date] toDate:destinationDate options:0];
[datelabel setText:[NSString stringWithFormat:#"%d%c %d%c %d%c %d%c", [components day], ' ', [components hour], ' ', [components minute], ' ', [components second], ' ']];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
destinationDate = [[NSDate dateWithTimeIntervalSince1970:1343609103] retain];
timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateLabel) userInfo:nil repeats:NO];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#end
set repeats YES to your timer.
[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(updateLabel) userInfo:nil repeats:YES];
edit: also consider using NSDateFormatter to display your string.
If you want to improve your layout, I would suggest using NSDateFormatter in conjunction with multiple UILabels. The date formatter can be used to create a string of the format you require and each label can hold a particular part of the date/time string. Take a look at Apple's Data Formatting Guide the most understated part is the link to the Unicode Technical Standard #35 which defines all the formats you can use.
Once you've split your date, you just have to layout your views as you like.
Related
I am back again with my pigs (means cochon in French)! :)
I would like to created a at simple animated image with an NSTimer and I can't find example of it not with the iphone SDK.
after 3 second, the debugger displays : Program received signal: “EXC_BAD_ACCESS”
here is the code, if you have some time to check it and say what you think of it..
#import <Cocoa/Cocoa.h>
#interface maatView : NSView {
NSArray *mesImagesCochon;
NSImageView * monCochon;
int counter;
}
-(void)tick;
#end
here is the .m file:
#import "maatView.h"
#implementation maatView
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if (self) {
// Initialization code here.
}
return self;
}
- (void)awakeFromNib
{
counter=0;
mesImagesCochon = [NSArray arrayWithObjects:
[NSImage imageNamed:#"cochon.png"],
[NSImage imageNamed:#"cochon2.png"],
[NSImage imageNamed:#"cochon3.png"],
[NSImage imageNamed:#"cochon4.png"],
nil];
[NSTimer scheduledTimerWithTimeInterval:3
target:self
selector:#selector(tick)
userInfo:nil
repeats:NO];
monCochon = [[NSImageView alloc]init];
[monCochon setFrame:NSMakeRect(0, 0, 100, 100)];
}
- (void)drawRect:(NSRect)dirtyRect {
// Drawing code here.
}
-(void)tick
{
NSLog(#"method appele %d",mesImagesCochon.count);
counter++;
if (counter > mesImagesCochon.count)
{
counter = 0;
}
[monCochon setImage:[mesImagesCochon objectAtIndex:counter]];
[self addSubview:monCochon];
}
#end
Im trying to get a scanned QR code to display a view controller with information about the item the code represents. When I try and segue to the detail view controller, it comes up with:
Warning: Attempt to present <MachinesDetailViewController: 0x1e5bfc50> on <UITabBarController: 0x1f867d90> whose view is not in the window hierarchy!
The MainViewController is withing a main tab bar controller, but the detail view controller is within a navigation controller which is withing the tab bar controller.
Heres my MainViewController.m where this is sitting.
//
// FirstViewController.m
// Fitness Plus+
//
// Created by Tom Brereton on 26/01/13.
// Copyright (c) 2013 Tom Brereton. All rights reserved.
//
#import "MainViewController.h"
#import "MachinesDetailViewController.h"
#interface MainViewController ()
#end
#implementation MainViewController
#synthesize resultText, machineKeys, codeInt, machineArea, machineName;
- (IBAction)scanButton:(id)sender {
NSLog(#"ehe");
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [[ZBarReaderViewController alloc] init];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
NSLog(#"Got here");
// present and release the controller
[self presentViewController: reader
animated: YES
completion:nil];
}
- (void) imagePickerController: (UIImagePickerController*) reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
NSLog(#"Naht Here");
// EXAMPLE: do something useful with the barcode data
// Scan the machines.plist array and print it to the console.
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"machines" ofType:#"plist"];
NSDictionary *machineDict = [NSDictionary dictionaryWithContentsOfFile:filePath];
machineKeys = [machineDict objectForKey:#"Exercises"];
machineArea = [machineDict objectForKey:#"Area"];
resultText.text = symbol.data;
//Convert code into integer value and put it inside codeInt
codeInt = [symbol.data intValue];
NSLog(#"Scanned Value: %#", [machineKeys objectAtIndex:codeInt]);
// EXAMPLE: do something useful with the barcode image
[self performSegueWithIdentifier:#"showDetailFromMain" sender:reader];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)reader {
if ([[segue identifier] isEqualToString:#"showDetailFromMain"]) {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
MachinesDetailViewController *machineViewController = [storyboard instantiateViewControllerWithIdentifier:#"showMachineDetailViewController"];
machineViewController = [segue destinationViewController];
machineName = [machineKeys objectAtIndex:codeInt];
[machineViewController setMachineNameLabel: machineName];
}
}
- (void) viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
The ZBar stuff is just relating to the QR scanning API.
And here is the MachineDetailsViewController.m.
//
// MachinesDetailViewController.m
// Fitness Plus+
//
// Created by Tom Brereton on 27/01/13.
// Copyright (c) 2013 Tom Brereton. All rights reserved.
//
#import "MachinesDetailViewController.h"
#interface MachinesDetailViewController ()
#property(nonatomic, copy) NSString *title;
#end
#implementation MachinesDetailViewController
#synthesize machineLabel, machineName, instructionsLabel, typeLabel, mainMuscleLabel, otherMuscleLabel, equipmentLabel, machineDictionary, machineArray, mainMuscleLabelString, instructionLabelString, typeLabelString, otherMuscleLabelString, equipmentLabelString, title, machineNameLabel;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
// Set the Label text with the selected machine name
machineName = machineNameLabel;
mainMuscleLabel.text = mainMuscleLabelString;
otherMuscleLabel.text = otherMuscleLabelString;
equipmentLabel.text = equipmentLabelString;
typeLabel.text = typeLabelString;
instructionsLabel.text = instructionLabelString;
self.navigationItem.title = machineName;
NSLog(#"got it");
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#end
Thanks, if you need more info just ask.
Tom
Struggled with the exact same issue,
my solution was to call the segue this way:
[reader dismissViewControllerAnimated:YES completion:^{
NSLog(#"Perform segue");
[self performSegueWithIdentifier:#"showDetailFromMain" sender:self];
}];
I also had to connect the segue to the view and not to a single button.
Hope this works for you.
I am erroring out with Bool and before I added a modal view and now it says bool is undefined. I dont understand why that is unless its because I'm using another nib for my modal view.
Do I need to call or change my boon now. Please advise.
//
// UrbanAgentViewController.m
// UrbanAgent
//
// Created by Dwayne Stephens on 4/2/12.
// Copyright 2012 __MyCompanyName__. All rights reserved.
//
#import "UrbanAgentViewController.h"
#import "NewContactController.h"
#implementation UrbanAgentViewController
// our own buttonTapped method
-(IBAction) buttonTapped: (id) sender {
NewContactController *ivc = [[NewContactController alloc] init];
ivc.delegate = self;
UINavigationController *nc = [[UINavigationController alloc]
initWithRootViewController:ivc];
[self presentModalViewController:nc animated:YES];
[ivc release];
[nc release];
}
-(void) doneButtonPressed: (NSArray *) values
{
[self dismissModalViewControllerAnimated:YES];
NSString *message =
[[NSString alloc]
initWithFormat:#"The values were %#, %#, %#, %#, %#, and %#",
[values objectAtIndex:0], [values objectAtIndex:1], [values objectAtIndex:2],
[values objectAtIndex:3], [values objectAtIndex:4], [values objectAtIndex:5]];
UIAlertView *alert =
[[UIAlertView alloc] initWithTitle:#"Values Passed"
message:message delegate:nil
cancelButtonTitle:#"Excellent!" otherButtonTitles:nil ];
[alert show];
[alert release];
[message release];
/*
// The designated initializer. Override to perform setup that is required before the view is loaded.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
*/
/*
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView {
}
*/
/*
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
}
*/
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
return YES;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (void)dealloc {
[super dealloc];
}
#end
You need a closing curly brace on doneButtonPressed:.
I have an app that uses a UIWebView on one of it's tabs.
Everything is working like it should, but the speed that the view is scrolling is extremely slow! It doesn't matter if I build it in the simulator or if I build it in my iPhone, it's the same slow scroll.
How can I increase the scrolling speed of the view? I've noticed that it will stop scrolling as soon as the finger leaves the screen, instead of keep scrolling and decelerate like in safari, does this have anything to do with it?
The is my .h file:
// FirstViewController_SE.h
// WebApp
//
// Created by Camilla Fröberg on 2012-03-29.
// Copyright (c) 2012 SafeLine Sweden AB. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface FirstViewController_SE : UIViewController<UIWebViewDelegate> {
IBOutlet UIWebView *webDisplay_SE;
UIBarButtonItem* mBack;
UINavigationItem* back;
}
#property(nonatomic,retain) UIWebView *webDisplay_SE;
#property (nonatomic, retain) IBOutlet UIBarButtonItem* back;
- (void)updateButtons;
#end
And this is my .m file:
//
// FirstViewController_SE.m
// WebApp
//
// Created by Camilla Fröberg on 2012-03-29.
// Copyright (c) 2012 SafeLine Sweden AB. All rights reserved.
//
#import "FirstViewController_SE.h"
#interface FirstViewController_SE ()
#end
#implementation FirstViewController_SE;
#synthesize webDisplay_SE;
#synthesize back = mBack;
#pragma mark - View lifecycle
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
self.webDisplay_SE.delegate = self;
NSString *urlAddress = #"http://www.safeline.eu/mobile/se/product";
//Create a URL object.
NSURL *url = [NSURL URLWithString:urlAddress];
//URL Requst Object
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
//Load the request in the UIWebView.
[webDisplay_SE loadRequest:requestObj];
[self updateButtons];
}
- (void)viewDidUnload {
self.back = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return YES;
}
- (void)updateButtons
{
self.back.enabled = self.webDisplay_SE.canGoBack;
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (BOOL)webDisplay_SE:(UIWebView *)webDisplay_SE shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
return YES;
}
- (void)webViewDidStartLoad:(UIWebView *)webDisplay_SE
{
[self updateButtons];
}
- (void)webViewDidFinishLoad:(UIWebView *)webDisplay_SE
{
[self updateButtons];
}
#end
Try this:
webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
Note: there's a bug in iOS 9 that you may need to workaround https://stackoverflow.com/a/32843700/308315
I am having a real problem finding where my problem is in my search controller. This is a table view with search bar and search display controller. It used to work fine, but all the sudden it stopped working. I turned on NSZombieEnabled and it shows that my NSArray called searchDataSource is the zombie.
When you type a search term the "shouldReloadTableForSearchTerm" executes the handleSearchForTerm function. The handleSearchForTerm" function accesses my ProductInfo class that query a SQLite database and returns the query results. Those results are then placed in my searchDataSource Array. Everything appears to work fine there. However, once I get to the "cellForRowAtIndexPath" function and I try to load the cells from the searchDataSource, that is when I run in to the problem of the Array having been deallocated.
Here is my code for the search controller:
//
// SearchViewController.h
// Priority Wire
//
// Created by Keith Yohn on 2/2/11.
// Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import <UIKit/UIKit.h>
#interface FourthViewController : UIViewController <UITableViewDataSource, UITableViewDelegate, UISearchDisplayDelegate, UISearchBarDelegate> {
UITableView *mainTableView;
NSArray *searchDataSource;
NSMutableArray *contentsList;
NSMutableArray *searchResults;
NSString *savedSearchTerm;
NSString *webURL;
}
#property (nonatomic, retain) IBOutlet UITableView *mainTableView;
#property (nonatomic, retain) IBOutlet NSArray *searchDataSource;
#property (nonatomic, retain) NSMutableArray *contentsList;
#property (nonatomic, retain) NSMutableArray *searchResults;
#property (nonatomic, copy) NSString *savedSearchTerm;
#property (nonatomic, retain) NSString *webURL;
- (void)handleSearchForTerm:(NSString *)searchTerm;
#end
SearchViewController.m
//
// SearchViewController.m
// Priority Wire
//
// Created by Keith Yohn on 2/2/11.
// Copyright 2011 Priority Wire & Cable. All rights reserved.
//
#import "FourthViewController.h"
#import "ProductsDatabase.h"
#import "ProductInfo.h"
#import "WebViewController.h"
#implementation FourthViewController
#synthesize mainTableView;
#synthesize searchDataSource;
#synthesize contentsList;
#synthesize searchResults;
#synthesize savedSearchTerm;
#synthesize webURL;
- (void)viewDidLoad {
[super viewDidLoad];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [self.searchDataSource count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
}
// Set up the cell...
ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row]; //This is where I get the 'message sent to deallocated instance' message.
[cell.textLabel setText:info.sName];
[cell.detailTextLabel setText:info.sType];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
ProductInfo *info = [searchDataSource objectAtIndex:indexPath.row];
webURL = [NSString stringWithFormat:#"http://www.prioritywire.com/specs/%#", info.sFile];
WebViewController *wvController = [[WebViewController alloc] initWithNibName:#"WebViewController" bundle:[NSBundle mainBundle]];
wvController.URL = webURL;
wvController.navTitle = #"Spec Sheet";
[self.navigationController pushViewController:wvController animated:YES];
[wvController release];
}
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Relinquish ownership any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Save the state of the search UI so that it can be restored if the view is re-created.
[self setSavedSearchTerm:[[[self searchDisplayController] searchBar] text]];
[self setSearchResults:nil];
}
- (void)dealloc {
[searchDataSource release], searchDataSource = nil;
[mainTableView release];
[contentsList release];
[searchResults release];
[savedSearchTerm release];
[super dealloc];
}
- (void)handleSearchForTerm:(NSString *)searchTerm
{
[self setSavedSearchTerm:searchTerm];
if ([self searchResults] == nil)
{
NSMutableArray *array = [[NSMutableArray alloc] init];
[self setSearchResults:array];
[array release], array = nil;
} else {
NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
self.searchDataSource = productInfo;
[self.mainTableView reloadData];
[productInfo release];
}
[[self searchResults] removeAllObjects];
if ([[self savedSearchTerm] length] != 0)
{
for (NSString *currentString in [self contentsList])
{
if ([currentString rangeOfString:searchTerm options:NSCaseInsensitiveSearch].location != NSNotFound)
{
[[self searchResults] addObject:currentString];
}
}
}
}
#pragma mark -
#pragma mark UISearchDisplayController Delegate Methods
- (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldReloadTableForSearchString:(NSString *)searchString
{
[self handleSearchForTerm:searchString];
// Return YES to cause the search result table view to be reloaded.
return YES;
}
- (void)searchDisplayControllerWillEndSearch:(UISearchDisplayController *)controller
{
[self setSavedSearchTerm:nil];
self.searchDataSource = nil;
[self.mainTableView reloadData];
}
#end
I am quite new to objective-C and can't understand what I did wrong. I have spent days trying to figure this out and have had no luck. I would appreciate any help anyone can offer.
Keith
This bit of code seems to be the only place searchDataSource gets set:
NSArray *productInfo = [[ProductsDatabase database] searchListing:searchTerm];
self.searchDataSource = productInfo;
[self.mainTableView reloadData];
[productInfo release];
If ProductsDatabase follows the rules, you don't own the returned array (i.e. it is already autoreleased) so the release on the fourth line is incorrect.
Don't you mean to use your searchResults-array instead of your searchDataSource, because in handleSearchForTerm: you are adding the results to it. Why do you even have the searchResult ivar? It's only used in handleSearchForTerm:, maybe some mixup there?