《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],因为是坐标系都是用的正方形盖过去的,可以想象,南北极这种地方肯定盖不住了,就忽略了。。。于是,企鹅和北极熊表示强烈抗议。。。。

时间: 2024-07-28 14:08:41

《iOS6 application development》学习之路:No.5: __bridge,NSTimer和圆角的相关文章

《iOS6 application development》学习之路:No.1

虽然开始学习iOS的开发是在XCode5.1之后,而且默认的部署环境也都是iOS7的了,但是舍不得越狱的我的小4,况且也带不动iOS7,不过还好找到了可以把程序部署到我的iOS6系统上的方法http://blog.csdn.net/u011156012/article/details/30543471 入手<iOS6 Application Development>这本书已经1周了,感觉看起来很舒服,从简单到复杂,循序渐进,不断深入学习iOS开发的种种.今天进入到第11章:实现多场景和弹出框.

《iOS6 application development》学习之路:No.2

开始之前先说几个关键字吧  @property中的weak, nonatomic 和strong weak告诉系统,补在使用引用对象时,可将其从内存中删去.nonatomic告诉系统,不用担心应用程序的不同部分同时使用该属性的问题.几乎在任何情况下,都将使用这两个特性. 但是有时候需要使用特性 strong代替weak. weak能让Xcode更高效地将对象从内存中清除.还能避免所谓的循环引用(circular reference),即由于以下的原因,不能把对象从内存中清除:它引用了一个另一个对

《iOS6 application development》学习之路:No.3: 自定义选择器

先看下程序跑起来的样子吧,没有做任何,任何界面上的优化,所以请忽视丑陋的页面. 总共就两个,第一个页面是inital页面,中间一个label用来显示用户做的不同选择,下方是一个放在tool bar里面的button,用户点击后可以进行两个页面的切换.第2个页面总共有3个空间,最上端是一个自定义的pick view,两列,第一列显示动物的图片,第二列显示动物的叫声.中间是一个label,最下端是一个按钮,点击按钮后用来返回上一个页面. 因为教材中是按照功能拆分了一块一块讲解的,所以这次分别把2个页

《iOS6 application development》学习之路:No.6:两种实现动画的方法

在看iOS6应用开发时,介绍了一种播放动画的效果,其实就是一组数组,里面以此存储了很多张图片,相当于GIF图片的每一帧动画,然后在规定的时间内把他们都播放出来,这样就相当于实现动画了:后来又发现可以用另一种方式实现动画,就是利用Timer,然后再设置一个计数器,根据计数器的不同变化,然后实时改变控件的位置. 直接上代码: #import "ViewController.h" @interface ViewController (){ int _episodeNumber; //sing

Qt 学习之路 2 --- 读书笔记

一.文章来由 来自豆子老师非常好的一本Qt教程,但是只有网络版,所以用这个做笔记了,不动笔墨不读书嘛~~ 二.读书笔记 1.Qt 学习之路 2(2):Qt 简介 1.1 关于 Qt 的一站式解决 Qt 是一个著名的 C++ 应用程序框架.但并不只是一个 GUI 库,因为 Qt 十分庞大,并不仅仅是 GUI 组件.使用 Qt,在一定程度上你获得的是一个"一站式"的解决方案:不再需要研究 STL,不再需要 C++ 的,不再需要到处去找解析 XML.连接数据库.访问网络的各种第三方库,因为

Webwork 学习之路(六)Action 调用

阅读目录 1.这部分框架类关系 2.Webwork 获取和包装 web 参数 3.DefaultActionProxyFactory.DefaultActionProxy.DefaultActionInvocation       一路走来,终于要开始 webwork 核心业务类的总结,webwork 通过对客户端传递的 web 参数重新包装,进行执行业务 Action 类,并反馈执行结果,本篇源码分析对应下图 WebWork 框架流转图中红色框的地方. 回到顶部 1.这部分框架类关系 回到顶部

.Net程序员安卓学习之路4:使用xutils Get Post数据

原文:.Net程序员安卓学习之路4:使用xutils Get Post数据 前面使用了一些网络上找来的类进行网络访问,后来发现了安卓开发中有一个国人写的类库xutils比较全面,也比较经典,故后续使用xutils类库进行记录. 本例服务端使用WCF来实现,写好的WCF服务端在:http://www.cnblogs.com/madyina/p/3454741.html 下载部署即可 该服务说明如下: 这4个公开方法均返回一个User对象,其中最后一个还接收一个User对象. 下面我们就分别请求这4

F#学习之路(2) 深刻理解函数(上)

函数在函数式编程语言中是一等公民,是函数式语言中最重要的基本组成元素,也是其名称的由来. F# 中的函数之如C#中的类,是组织程序结构的最基本单元.是命令式编程语言中函数或OO编程语言中方法的超集.超集,有多强大?我将在下面几个方面细细道来. F#是一种多范式的编程语言.支持命令式.函数式.面向对象的编程范式,还有目前火热的面向语言编程(DSL).本文不会介绍其他的编程范式,只介绍函数式编程范式. 在面向对象编程的世界里,视命令式或过程式是一种丑陋的编程方式,至少被大多数程序员视为不能有效发挥O

Qt学习之路(23):自定义事件

Qt允许你创建自己的事件类型,这在多线程的程序中尤其有用,当然,也可以用在单线程的程序中,作为一种对象间通讯的机制.那么,为什么我需要使用事件,而不是使用信号槽呢?主要原因是,事件的分发既可以是同步的,又可以是异步的,而函数的调用或者说是槽的回调总是同步的.事件的另外一个好处是,它可以使用过滤器. Qt中的自定义事件很简单,同其他类似的库的使用很相似,都是要继承一个类进行扩展.在Qt中,你需要继承的类是QEvent.注意,在Qt3中,你需要继承的类是QCustomEvent,不过这个类在Qt4中