閱讀870 返回首頁    go 阿裏雲 go 技術社區[雲棲]


《iOS6 application development》學習之路:No.5: __bridge,NSTimer和圓角

關於__bridge,第一次碰到類型轉換的時候,沒有注意到前麵是兩個_的。廢話不多說,進入正題:

由於ARC不能管理Core Foundation Object的生命周期,所以在Core Foundation和ARC之間,我們需要使用到__bridge,__bridge_retained和__bridge_transfer三個轉換關鍵字。

根據蘋果官方的文檔(https://developer.apple.com/library/ios/#releasenotes/ObjectiveC/RN-TransitioningToARC/Introduction/Introduction.html):
__bridge隻做類型轉換,但是不修改對象(內存)管理權;
__bridge_retained(也可以使用CFBridgingRetain)將Objective-C的對象轉換為Core Foundation的對象,同時將對象(內存)的管理權交給我們,後續需要使用CFRelease或者相關方法來釋放對象;

__bridge_transfer(也可以使用CFBridgingRelease)將Core Foundation的對象轉換為Objective-C的對象,同時將對象(內存)的管理權交給ARC。

NSTimer

API裏麵NSTimer 是木有暫停繼續的方法的,隻有fire和invalidate,前者是開工的意思,後者是廢掉的意思,如果用廢掉來代替暫停的功能?顯然是不對的。那腫麼辦呢?其實NSTimer 有一個屬性叫 fireDate ,啥意思呢?fireDate麼,就是fire 的開始時間所以我們就有了思路了。

暫停: [timer setFireDate:[NSDate distantFuture]]; 

distantFuture,就是問你未來有多遠呢?好遠好遠就是無法到達的時間,所以 timer就一直等待不 fire了。也就是暫停了。

繼續: [timer setFireDate:[NSDate date]]; 

這個當然就是把fire 的時間設置為當前時刻,所以timer就立刻開工啦!

圓角按鈕

在做開發的過程中,發現XCode5.x和iOS7.x中的按鈕沒有以前的圓角模式了,google了一下發現了正解:

在Xcode 4的圓形按鈕...似乎已被替換...”.

確認它肯定 有 被取代:

圓角矩形按鈕被棄用的iOS 7.相反,使用
  係統按鈕,也就是說,類型UIButtonTypeSystem的一個UIButton對象.

7的iOS係統的按鈕不包括邊框或背景的外觀.
  係統按鈕可以包含一個圖形符號或文字標題,它
  可以指定一個色調的顏色或接受其父的顏色.

...

如果你需要顯示一個按鈕,包括邊框,使用一個按鈕
  輸入UIButtonTypeCustom並提供一個自定義的背景圖片.

Apple iOS 7 Transition Guide 號碼. 45,“圓角矩形按鈕”

所以,蘋果公司的建議是使用一個背景圖像.

但是不是說我們就真的沒有辦法使用圓角的按鈕了,雖然在IB中沒法設定按鈕為圓角,但是我們仍然可以通過在程序中手動更改按鈕的形狀,位置,背景顏色等等:

self.goButton.backgroundColor = [UIColor greenColor];
    [self.goButton.layer setMasksToBounds:YES];
    [self.goButton.layer setCornerRadius:10.0];
    [self.goButton.layer setBorderWidth:2.0];
    [self.goButton.layer setBorderColor:(__bridge CGColorRef)([UIColor redColor])];
    [self.goButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
之前google了一下, 說setMasksToBounds是必須的,不然會改掉後麵的背景,但是我實際中發現設置成YES和NO都沒有反應。

setCornerRadius 就是指定圓角的弧度,如果你設置成了90°,嗬嗬,自己試驗下是什麼效果吧。

setBorderwidth和color是設置邊框的顏色和寬度。注意顏色需要用到CGColorRef,這裏需要使用開篇介紹的__Bridge做類型轉化。不過值得一提的是,這個轉換是XCode的錯誤糾正機製提示我完成的,讚一個。


一個程序:

程序截圖我就不放了,很簡單,一個label,兩個按鈕,讓點擊go的時候,開始數數,0.1秒+1, 顯示在label上,然後go按鈕變成stop,點擊後暫停計時,再點一下繼續;另一個按鈕是restart。直接上代碼。

.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

@property (weak, nonatomic) IBOutlet UILabel *theCount;
@property (weak, nonatomic) IBOutlet UIButton *goButton;
@property (weak, nonatomic) IBOutlet UIButton *restartButton;

- (void)countUp;
- (IBAction)click:(id)sender;
- (IBAction)reStart:(id)sender;

@end

.m

#import "ViewController.h"

@interface ViewController (){
    int _count;
    UIBackgroundTaskIdentifier _counterTask;
    NSTimer* _theTimer;
}

@end

@implementation ViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    _counterTask = [[UIApplication sharedApplication]
                    beginBackgroundTaskWithExpirationHandler:^{
                        //
                    }];
    _count = 0;
    
    //set the button's style
//    self.goButton.frame = CGRectMake(40, 400, 50, 30);
    self.goButton.backgroundColor = [UIColor greenColor];
    [self.goButton.layer setMasksToBounds:YES];
    [self.goButton.layer setCornerRadius:10.0];
    [self.goButton.layer setBorderWidth:2.0];
    [self.goButton.layer setBorderColor:(__bridge CGColorRef)([UIColor redColor])];
    [self.goButton setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];
    

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)countUp{
    if (_count ==1000) {
        [_theTimer invalidate];
        _theTimer = nil;
        [[UIApplication sharedApplication] endBackgroundTask:_counterTask];
    } else {
        _count++;
        NSString* currentCount;
        currentCount = [[NSString alloc] initWithFormat:@"%d",_count];
        self.theCount.text = currentCount;
    }
}

- (IBAction)click:(id)sender {
    if ([self.goButton.titleLabel.text isEqualToString:@"Go"]) {
        [self.goButton setTitle:@"Stop" forState:UIControlStateNormal];
        if (_count == 0) {
            _theTimer =[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(countUp) userInfo:nil repeats:YES];
        }else{
            [_theTimer setFireDate:[NSDate date]];
        }
    } else {
        [self.goButton setTitle:@"Go" forState:UIControlStateNormal];
        //Pause;
        [_theTimer setFireDate:[NSDate distantFuture]];
    }
    
}

- (IBAction)reStart:(id)sender {
    [_theTimer invalidate];
    _count = 0;
    _theTimer = [NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(countUp) userInfo:nil repeats:YES];
}


@end

最後說個小插曲,之前想試驗一個程序,就是在地圖上顯示一個圖釘坐標,但是怎麼試都不行,各種崩潰。。。後來研究了半天發現。。。是坐標給錯了,然後在wiki上研究了半天坐標係,經度的範圍是【-180,180】,緯度的範圍是[-85.xxxx , 85.xxx]為什麼緯度不是[-90,90],因為是坐標係都是用的正方形蓋過去的,可以想象,南北極這種地方肯定蓋不住了,就忽略了。。。於是,企鵝和北極熊表示強烈抗議。。。。

最後更新:2017-04-03 05:38:55

  上一篇:go 從產品角度考慮優秀員工的評定
  下一篇:go C#讀書筆記