《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
上一篇:
从产品角度考虑优秀员工的评定
下一篇:
C#读书笔记
ORACLE备份
shiro
如何使用阿里云幸运券--你知道阿里云幸运券可以扩大优惠幅度吗?
myeclipse+tomcat中出现org.apache.juli.logging.LogFactory以及ECLIPSE里org.apache.catalina.startup.Bootstrap
阿里巴巴大数据学院落地成都,计划5年培养2000名高端专业人才
ALICloudDB for PostgreSQL 试用报告 - 4 水平分库 之 节点扩展
客户端的web技术
《Spring实战(第4版)》——第2章 装配Bean 2.1Spring配置的可选方案
获取当前经纬度方法
String-字符串类