2014年7月28日 星期一

頁面轉換


UIViewController *page2 = [self.storyboard instantiateViewControllerWithIdentifier:@"page2"];

Modal
[self presentViewController:page2 animated:YES completion:NULL];
The completion block is used for doing any tasks after presenting the view controller , the code written inside the completion block will execute only after the view is presented.
資料來源:http://stackoverflow.com/a/13025138

Push
[self.navigationController pushViewController:page2 animated:YES];

UIButton

設定按鈕上的文字
[self.button setTitle:@"Wake Up" forState:UIControlStateNormal];
不能用
self.button.titleLabel.text = @"Wake Up";

2014年7月17日 星期四

Core Data 基本操作


查詢
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"GoToBedTime" inManagedObjectContext:self.managedObjectContext];
NSSortDescriptor *sortByDate = [[NSSortDescriptor alloc] initWithKey:@"date" ascending:NO];
NSArray *sortArray = [[NSArray alloc] initWithObjects:sortByDate, nil];
fetchRequest.sortDescriptors = sortArray;
fetchRequest.entity = entity;
NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:nil];
GoToBedTime *goToBedTime = [array objectAtIndex:0];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"HH:mm:ss"];
cell.detailTextLabel.text = [formatter stringFromDate:goToBedTime.date];

原本
WakeUpTime *wakeUpTime = [array objectAtIndex:0];
wakeUpTime.timing
優化
[[array objectAtIndex:0] timing]

handle the error
NSError *error = nil;
NSArray *array = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error]; //沒有資料會取得零筆資料但不會有error
if (error) {
     //handle the error
}

相關範例
https://www.facebook.com/groups/iostw/permalink/969502549743761/

將NSDate轉成NSString


NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"HH:mm:ss"];
cell.detailTextLabel.text = [formatter stringFromDate:[NSDate date]];

2014年7月16日 星期三

關於UINavigationController

在網路上看到一段關於UINavigationController的解釋,我覺得寫得非常好



出處:http://youyuge.com/2013/01/09/Learn-iOS-Development-UITabBarController-And-Review.html

2014年7月10日 星期四

tableView

重新載入資料

全部
[self.tableView reloadData];
更新特定row
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
別人的文章:UITableViewController 之 dataSource 更新顯示


不知道什麼時候要加@@
[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"Cell"];


設定接下來要顯示的viewController的title,有兩種方式:

prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    UIViewController *page2 = segue.destinationViewController;
    NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
    (indexPath.row == 0) ? [page2 setTitle:@"Go To Bed Time"] : [page2 setTitle:@"Wake Up Time"];
}

didSelectRowAtIndexPath,需要另外設定目標viewController的Storyboard ID。但如果需要隔空轉換畫面,也就是不用segue轉換畫面的話,比如:同一個button一不同的情況要轉換到不同的view:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    UIViewController *page2 = [self.storyboard instantiateViewControllerWithIdentifier:@"page3"];
    (indexPath.row == 0) ? [page2 setTitle:@"Go To Bed Time"] : [page2 setTitle:@"Wake Up Time"];
    [self.navigationController pushViewController:page2 animated:YES];
}

如果轉換模式要用modal
[self presentViewController:page2 animated:YES completion:nil];
completion那裡可以放轉換過去後要執行的程式

indexPath

The NSIndexPath class represents the path to a specific node in a tree of nested array collections.
A table has sections and rows, to know where a row is you need to know the index of which section it is in and the index position it is at within that section.
UIKit adds a category to make it easier to work with UITableView's.
@interface NSIndexPath (UITableView)

+ (NSIndexPath *)indexPathForRow:(NSInteger)row inSection:(NSInteger)section;

@property(nonatomic,readonly) NSInteger section;
@property(nonatomic,readonly) NSInteger row;

@end
資料來源:http://stackoverflow.com/a/10807882/3295047

2014年7月9日 星期三

按下backButton所觸動的method

我總共查到四種方法:

方法一:viewWillDisappear
-(void) viewWillDisappear:(BOOL)animated {
    if ([self.navigationController.viewControllers indexOfObject:self]==NSNotFound) {
       // back button was pressed.  We know this is true because self is no longer
       // in the navigation stack.  
    }
}

方法二:viewDidDisappear
- (void)viewDidDisappear:(BOOL)animated
{
    if (self.navigationController == nil) {
        NSLog(@"self.navigationController == nil");
    }
    if (self.navigationController.view == nil) {
        NSLog(@"self.navigationController.view == nil");
    }
    if (self.navigationController.viewControllers == nil) {
        NSLog(@"self.navigationController.viewControllers = nil");
    }
}

方法三:willMoveToParentViewController:parent
-(void)willMoveToParentViewController:(UIViewController *)parent {
    NSLog(@"This VC has has been pushed popped OR covered"); 
    if (!parent)
        NSLog(@"This happens ONLY when it's popped");
}
使用這個方法有個問題,就是不知道為什麼進入這個viewController也會觸動這個method



方法四:重新寫一個UINavigationBar,把舊的覆蓋掉
Add this custom Button on UINavigationBar , just override this button on BackButton and you can perform any action with click event.
- (void)viewDidLoad
{
        UIImage *backButtonImage = [UIImage imageNamed:@"backbutton.png"];
        UIButton *backbutton = [UIButton buttonWithType:UIButtonTypeCustom];
        //[backbutton setImage:backButtonImage forState:UIControlStateNormal];//this line for set only image on button
        [backbutton setBackgroundImage:backButtonImage forState:UIControlStateNormal];
        [backbutton setTitle:@"Back" forState:UIControlStateNormal];
        backbutton.frame = CGRectMake(0, 0, backButtonImage.size.width, backButtonImage.size.height);
        UIBarButtonItem * back = [[UIBarButtonItem alloc] initWithCustomView:backbutton];
        [backbutton addTarget:self action:@selector(back_Clicked) forControlEvents:UIControlEventTouchUpInside];
        self.navigationItem.leftBarButtonItem = back;
}
when back button clicked bellow method call and you will go to previous viewcontroller.
-(void)back_Clicked{
      [self.navigationController popViewControllerAnimated:YES];
}
出處:http://stackoverflow.com/a/13856441/3295047

不過只不過為了取得觸發按backButton的method有點太大費周章了,原出處是想要自訂UINavigationBar



方法五:下面這幾種方法也是網路上找到的,但不知道為什麼都不能觸發,原因可能是因為在tab下無法啟動,但不知道為什麼我另外開了個project還是不行,以後再來找原因吧,如果有誰知道拜託告訴我~~
- (void)navigationController:(UINavigationController *)navigationController
      willShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animated
{
    NSLog(@"navigationController:willShowViewController:animated");
}

- (void)navigationBar:(UINavigationBar *)navigationBar
           didPopItem:(UINavigationItem *)item
{
    NSLog(@"navigationBar:didPopItem");
    
}

- (UIViewController *)popNavigationItemAnimated:(BOOL)animated
{
    NSLog(@"popNavigationItemAnimated");
    return self.parentViewController;
}

- (id <UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController 
                                   animationControllerForOperation:(UINavigationControllerOperation)operation
                                                fromViewController:(UIViewController *)fromVC
                                                  toViewController:(UIViewController *)toVC
{
    NSLog(@"from VC class %@", [SLWakeUpTwoViewController class]);
    if ([fromVC isKindOfClass:[SLWakeUpTwoViewController class]])
    {
        NSLog(@"Returning from popped controller");
        
    }
    return nil;
}


延伸:如何直接回到 RootViewController(跳過中間的ViewController)

離開頁面dismissViewController

- (IBAction)cancel:(id)sender {
    [self dismissViewControllerAnimated:YES completion:nil];
}