What Is Software Design?

程式設計不是 “building software”,而是 “designing software”。

Is Design Dead?

軟體系統的設計是演進來的,不能一步到位,而是要藉由憑繁與使用者互動得到的回饋來修改系統設計。

Programming is Gardening, not Engineering

與其把程式設計比喻成蓋房子,實際上更像是園藝。

Orthogonality and the DRY Principle

所有程式設計活動其實都是維護,因為絕大部分的時間都在改code,寫一點改一點。即使是新專案,也很快需要回頭作修改。

顯示具有 objective c 標籤的文章。 顯示所有文章
顯示具有 objective c 標籤的文章。 顯示所有文章

2014年1月17日 星期五

判別 NSNumber 正確寫法

step1. 錯誤的寫法
NSNumber *value = [data objectForKey:@"samount"];
 if (value == 0)
     {
          NSLog(@" OK :) ");
     }
     else 
     {
          NSLog(@"  Bad :( ");
     }
step2.正確的用法
if ([value isEqual:@(0)])

2014年1月15日 星期三

ios UIImage URL 要讀取網路圖片

code範例:
NSURL *imageURL = [NSURL URLWithString:@"http://example.com/demo.jpg"];
NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
UIImage *image = [UIImage imageWithData:imageData];

2014年1月10日 星期五

Core Data 將設計出來的資料庫轉成 .h 與 .m

step1.
點擊 .xcdatamodel檔案 => add Entity => 新增你的Attributes


step2.點擊 Editor => Create NSManagedObject Subclass....





2014年1月9日 星期四

Core Data 新增版本

step1.新增一個model文件(xcdatamodel)


確認命名版本 建議在後面加上你的版本數字 以後好維護



右邊在選擇你現在需要的版本



2013年11月6日 星期三

判斷是否為 iPhone 5

#define iPhone5 ([UIScreen instancesRespondToSelector:@selector(currentMode)] ? CGSizeEqualToSize(CGSizeMake(640, 1136), [[UIScreen mainScreen] currentMode].size) : NO)


所以當使用時,僅需照以下寫法使用即可囉
if (iPhone5)
//do something for iPhone 5
else
//do something for iPhone 4s 4 3GS etc..

ios table view 要把 Header table 拿掉

//設置Header table的高度

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 1;

}

2013年10月17日 星期四

輸入Picker View 樣式 資料時 navigation bar 要灰色 不能使用

step1.

全域宣告


UIButton *barBlockBut;

 像是如下:

@interface SportViewController () <UITextFieldDelegate>

{
  UIButton *barBlockBut;
}

step2.


調用textFieldDidBeginEditing

- (void)textFieldDidBeginEditing:(UITextField *)textField

{

    if(textField == (sportTimeTextField 這裡填寫您輸入的textField))
    {
        if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1)         {
        self.view.window.tintAdjustmentMode = UIViewTintAdjustmentModeDimmed;
        }

        barBlockBut = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
        [self.navigationController.navigationBar addSubview:barBlockBut];
        
    }

}

step3.

- (void)textFieldDidEndEditing:(UITextField *)textField
{


   if(barBlockBut)
    {
        [barBlockBut removeFromSuperview];
        barBlockBut = nil;
        if (floor(NSFoundationVersionNumber) > NSFoundationVersionNumber_iOS_6_1) {
            self.view.window.tintAdjustmentMode = UIViewTintAdjustmentModeNormal;
            
        }
        
    }


}


ps:

記得 該UITextField  要設定

TextField.delegate = self;


2013年10月4日 星期五

ios7 status bar 隱藏 hide

ios7對於 狀態列有很大的改變

舊的程式碼為
[[UIApplication sharedApplication] setStatusBarHidden:YES withAnimation:UIStatusBarAnimationSlide];

不過在ios7中這個方法已經無法work了

解決方法1.

到infor.plist中 加入 key: UIViewControllerBasedStatusBarAppearance
設置為no

這樣就告訴系統說 status bar 不依賴 UIViewcontroller.

解決方法2.

- (UIStatusBarStyle)preferredStatusBarStyle { return UIStatusBarStyleLightContent; //UIStatusBarStyleDefault = 0 黑色文字,浅色背景时使用 //UIStatusBarStyleLightContent = 1 白色文字,深色背景时使用 }
上面的code是控制顯示時的樣式,下面的code是控制是否顯示status bar

調用以下的code 會觸發上面的code
- (BOOL)prefersStatusBarHidden { return NO; //返回NO表示要显示,返回YES将hiden }



[self setNeedsStatusBarAppearanceUpdate];

如果想加入動畫如下:

[UIView animateWithDuration:0.5 animations:^{ [self setNeedsStatusBarAppearanceUpdate]; }];


參考文獻:http://www.ifun.cc/blog/2013/09/28/ios7yin-cang-status-bar/

2013年9月11日 星期三

UITextField 設定 游標的 顏色 set color

step1.

宣告一個 UITextField *bmiTextField;

加入


 bmiTextField.delegate = self;



step2.

設定事件

- (void)textFieldDidEndEditing:(UITextField *)textField
{

      //確定text裡面有值
        if(textField.layer.borderWidth)
        {
            textField.layer.borderWidth = 0;
            textField.backgroundColor = [UIUtility greenColor];
            textField.textColor = [UIColor whiteColor];
           //設定游標顏色
            [[textField valueForKey:@"textInputTraits"] setValue:[UIColor whiteColor] forKey:@"insertionPointColor"];
        }

       
    }
//確定text裡面沒有值
    else
    {
        [[textField valueForKey:@"textInputTraits"] setValue:[UIColor blueColor] forKey:@"insertionPointColor"];
        textField.layer.borderWidth = 0.5;
        textField.backgroundColor = [UIColor whiteColor];
        textField.textColor = [UIColor blackColor];
    }
}

2013年9月5日 星期四

UITextField 後面加入小x 清除 輸入 資料 / 清除的事件

step1.


 UITextField *endTextField;


endTextField[[UITextField alloc] initWithFrame:CGRectMake(10, 50, 300, 30)];

    [contentBaseView addSubview:endTextField];

endTextField.delegate = self;
    
endTextField.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
    
//加入後面的小xx
endTextField.clearButtonMode = UITextFieldViewModeWhileEditing;

step2.

//這是textfield 清除的事件

-(BOOL)textFieldShouldClear:(UITextField *)textField
{
    //NSLog(@"check in textFieldShouldClear");
    textField.text = @"";
    self.period.endDate = nil;
    return YES;
}

NSUserDefaults Save/Read/Clear 儲存/讀取/清除

step1.
// 定義名稱 define key
#define kIsActive @"isActive"
#define kUserName @"userName"
step2.
// 讀取資料
-(void)loadInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSLog(@"Name : %@", [defaults stringForKey:kUserName]);
NSLog(@"isActive : %@", ([defaults boolForKey:kIsActive] ? @"YES" : @"NO"));
}
step3. 
// 儲存資料
-(void)saveInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *userName = @"Hank";
BOOL isActive = YES;
[defaults setObject:userName forKey:kUserName];
[defaults setBool:isActive forKey:kIsActive];
}
step4. 
// 清除資料
-(void)clearInfo {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:kUserName];
[defaults removeObjectForKey:kIsActive];
}
 
step5. 主程式
// 執行
- (void)viewDidLoad
{
[super viewDidLoad];
[self saveInfo];
[self loadInfo];
[self clearInfo];
[self loadInfo];
}

2013年8月16日 星期五

ios Observer Pattern 的 NSNotificationCenter 使用 用法


在Design Patterns 中的 Observer Pattern 主要目是用來解決一對多的物件之間的依附關係 ,只要物件狀態一有變動,就可以通知其他相依物件做跟更新的動作,舉個簡單的例子 Observer 就像是一個班級裡負責聯絡的窗口一樣,當班級內有人有訊息需要通知給所有人時,只要告訴這個聯絡窗口,之後就由聯絡窗口統一通知班級內的所有人,當然也包含發佈消息的這個人。在 Objective-C 裡我們並不需要真的去實作出 Observer Pattern,透過使用 NSNotificationCenter 也可以達到相同的效果。


在開始前

先做一個.h  and .m


例如 Constant.h  and .m

先建立一組字串方便以後的處理

.h如下
extern NSString *const FoodChangeNoti;

.m如下


NSString *const FoodChangeNoti = @"FoodChangeNoti";


接下來要用到的viewcontroller  記得要把


#import "Constant.h"  加進去




NSNotificationCenter 可分為三個部分

第一個部分是
註冊

step1


在viewcontroller中

@interface FoodDateViewController () 

{
//宣告一個

id notiObserver;

}

step2

在viewcontroller 的viewDidLoad加入創建


    __weak FoodDateViewController *selfController = self;

    notiObserver = [[NSNotificationCenter defaultCenter] addObserverForName:FoodChangeNoti object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
        [selfController updateUi];

    }];



-(void)updateUi
{
//在這裡面寫你要做的事情 例如更新畫面


}


第二個部分是
取消

step1

記得離開這個viewcontroller要把它釋放掉


-(void)dealloc
{
    if(notiObserver)
    {
        [[NSNotificationCenter defaultCenter] removeObserver:notiObserver];
        notiObserver = nil;
    }
    

}


setp2

在viewcontroller viewDidLoad 創建前也做一次釋放的動作

    if(notiObserver)
    {
        [[NSNotificationCenter defaultCenter] removeObserver:notiObserver];
        notiObserver = nil;
    }



第三個部分是
訊息通知

step1

發出通知


[[NSNotificationCenter defaultCenter] postNotificationName:FoodChangeNoti object:nil userInfo:nil];



參考文獻:http://furnacedigital.blogspot.tw/2011/09/observer-pattern-nsnotificationcenter.html

2013年8月12日 星期一

ios 6 and ios 7 處理 不能輸入未來時間的問題


step1

新增一個日期選擇器


MyPickerView *datePickerView;

step2

datePickerView = [MyPickerView getDatePickerViewWithBarForController:self title:@"select time" ];

datePickerView.datePickerView.datePickerMode = UIDatePickerModeDateAndTime;

datePickerView.datePickerView.maximumDate = [NSDate date];


[datePickerView.datePickerView addTarget:self action:@selector(dateChanged:) forControlEvents:UIControlEventValueChanged];

設定最大日期不能超過今天

step3

因為ios6 在秒上沒有處理得很好

再加上dateChanged的方法來處理

-(void)dateChanged:(UIDatePicker*)sender
{
    if([sender.date compare:sender.minimumDate] == NSOrderedSame)
    {
        NSDate* oneSecondAfterPickersDate = [sender.date dateByAddingTimeInterval:1] ;
        [sender setDate:oneSecondAfterPickersDate animated:YES];
    }
}

2013年8月8日 星期四

ios objective c #ifdef #endif #define #if 用法

1.情況


#define _xxx


#ifdef _xxx

程序1

#else

程序2

#endif

這表示 如果 _xxx 的字符 是否有被 #define 定義過 如果定義了就會跑入程序1(如上所示)


2.情況


#define _xxx


#ifndef _xxx

程序1

#else

程序2

#endif

这里使用了#ifndef,表示的是if not def

跟上面相反  如果 如上面會跑 程序2


3.情況


#if 常量

程序1

#else

程序2

 #endif

這裡表示 常量 為真的  (非0 隨便的數字只要不是0) ,就執行程序1






2013年8月6日 星期二

ios UILabel 在同一段文字上 做不同顏色的調整

step1
創造出一個 Label
  eatLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 20, 100, 30)];

  eatLabel.font = [UIFont systemFontOfSize:14];

step2.
創造出你要的文字 給予每ㄍㄜ

NSMutableAttributedString *str = [[NSMutableAttributedString alloc] initWithString:@"吃了  早餐"];
        [str addAttribute:NSForegroundColorAttributeName value:[UIColor 
orangeColor] range:NSMakeRange(0,2)];
        [str addAttribute:NSForegroundColorAttributeName value:[UIColor redColor] range:NSMakeRange(3,3)];

step3.

把字串接回 Label

    eatLabel.backgroundColor = [UIColor clearColor];
  eatLabel.attributedText = str;
        [self addSubview:eatLabel];

2013年7月25日 星期四

iOS 設計出 facebook 留言的 bottom bar 隨著 text 鍵盤上升出現





step1.
首先要創一個 ViewController 

step2.
ViewController 後面加上UITextViewDelegate 如下

@interface ViewController ()<UITextViewDelegate >

{
        UITextView * commentTextView;
        UITextView * realCommentTextView;
}


step3.
ViewController 的viewDidLoad

//新增一個bottomview

 UIToolbar *bottomView = [[UIToolbar alloc] initWithFrame:CGRectMake(0,[UIScreen mainScreen].bounds.size.height-49, 320, 49)];
    [self.view addSubview:bottomView];
    bottomView.backgroundColor = [UIColor blackColor];
    bottomView.tintColor = [UIColor grayColor];
    
//新增一個輸入textview

    commentTextView = [[UITextView alloc] initWithFrame:CGRectMake(8, 10, 250, 30)];
    [bottomView addSubview:commentTextView];
    commentTextView.delegate = self;
    commentTextView.backgroundColor = [UIColor whiteColor];
    [commentTextView.layer setCornerRadius:5];
    commentTextView.clipsToBounds = YES;
    [commentTextView.layer setBorderWidth: 1.0];
    [commentTextView.layer setBorderColor: [[UIColor grayColor] CGColor]];

    commentTextView.font = [UIFont systemFontOfSize:16];

//新增一個輸入button

    UIButton *commentButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    commentButton.frame = CGRectMake(265, 10, 45, 30);
    [commentButton setTitle:NSLocalizedString(@"Send", nil) forState:UIControlStateNormal];
    [bottomView addSubview: commentButton];
    [commentButton addTarget:self action:@selector(addCommentButPressed:) forControlEvents:UIControlEventTouchUpInside];

step4.

在新增點下後的樣子

//新增一個bottomview

UIToolbar *bottomView2 = [[UIToolbar alloc] initWithFrame:CGRectMake(0, [UIScreen mainScreen].bounds.size.height-20-44-49, 320, 49)];
    bottomView2.backgroundColor = [UIColor blackColor];
    bottomView2.tintColor = [UIColor grayColor];


//新增一個輸入textview   

    realCommentTextView = [[UITextView alloc] initWithFrame:CGRectMake(8, 10, 250, 30)];
    realCommentTextView.delegate = self;
    realCommentTextView.backgroundColor = [UIColor whiteColor];
    realCommentTextView.clipsToBounds = YES;
    [realCommentTextView.layer setCornerRadius:5];
    [bottomView2 addSubview:realCommentTextView];
    [realCommentTextView.layer setBorderWidth: 1.0];
    [realCommentTextView.layer setBorderColor: [[UIColor grayColor] CGColor]];
    realCommentTextView.font = [UIFont systemFontOfSize:16];
    
//新增一個輸入button

    UIButton *commentButton2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    commentButton2.frame = CGRectMake(265104530);
    [commentButton2 setTitle:NSLocalizedString(@"Send"nilforState:UIControlStateNormal];
    [bottomView2 addSubview: commentButton2];
    [commentButton2 addTarget:self action:@selector(addCommentButPressed:) forControlEvents:UIControlEventTouchUpInside];



step5.

讓點下後出現bottomView2

    commentTextView.inputAccessoryView = bottomView2;

step6.

加上UITextViewDelegate當輸入很多的時候高會改變並且開起scrolls

#pragma mark - UITextViewDelegate

- (void)textViewDidChange:(UITextView *)textView
{
    if(textView.contentSize.height > 50)
    {
        textView.superview.frame = CGRectMake(0, 0, 320, 98);
        textView.frame = CGRectMake(5, 14.5, 250, 60);
        [textView scrollsToTop];
    }
}


2013年7月19日 星期五

iOS 擊點背景讓textField鍵盤縮下去

step1.
新增一個UITextField出來

UITextField *myTextField=[[UITextField alloc]initWithFrame:CGRectMake(
121, 30, 159, 30) ];


 self.nameTextField.placeholder = @"請輸入xxxx";

self.myTextField.delegate = self ;//要設定代理人


step2.
設定按背景

if(&UIViewNoIntrinsicMetric)
{
        UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
        [self.view addGestureRecognizer:tapGesture];
        
}

step3. 按下後執行的副程式

-(void)tap:(id)sender
{
    [self.view endEditing:YES];
    //[ScrollView setContentOffset:CGPointMake(0, 0) animated:YES]; //會幫你移動道你要顯示的行數
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
    [textField resignFirstResponder];

    return YES;
}

=================================================

顯示keyboard:
[myTextField becomeFirstResponder];

隱藏keyboard:
[myTextField resignFirstResponder];

endEditing:的方法
下面介紹一下endEditing:的方法,該方法為UIView中的一個方法,定義為

- (BOOL)endEditing:(BOOL)force

官方原文

Causes the view (or one of its embedded text fields) to resign the first responder status.
This method looks at the current view and its subview hierarchy for the text field that is currently the first responder. If it finds one, it asks that text field to resign as first responder. If the force parameter is set to YES, the text field is never even asked; it is forced to resign.
翻譯為
註銷當前view(或它下屬嵌入的test fidlds)的first responder狀態
該方法在view中找到處於first responder狀態的test fiedld,如果找到會註銷其狀態,如果指定force參數為YES,則不再詢問test field,而直接強制註銷其他first responder狀態