一个java程序员自学IOS开发之路(十)

2015/11/26

Day 41

今天开始学起触摸事件

在用户使用app过程中,会产生各种各样的事件

iOS中的事件可以分为3大类型

响应者对象

在iOS中不是任何对象都能处理事件,只有继承了UIResponder的对象才能接收并处理事件。我们称之为“响应者对象”

UIApplication、UIViewController、UIView都继承自UIResponder,因此它们都是响应者对象,都能够接收并处理事件

UIResponder内部提供了以下方法来处理事件

  • 触摸事件

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

  • 加速计事件

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;

- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;

- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;

  • 远程控制事件

- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

UIView是UIResponder的子类,可以覆盖下列4个方法处理不同的触摸事件

  • 一根或者多根手指开始触摸view,系统会自动调用view的下面方法

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

  • 一根或者多根手指在view上移动,系统会自动调用view的下面方法(随着手指的移动,会持续调用该方法)

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

  • 一根或者多根手指离开view,系统会自动调用view的下面方法

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

  • 触摸结束前,某个系统事件(例如电话呼入)会打断触摸过程,系统会自动调用view的下面方法

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

提示:touches中存放的都是UITouch对象

  • 当用户用一根触摸屏幕时,会创建一个与手指相关联的UITouch对象
  • 一根手指对应一个UITouch对象

UITouch的作用

  • 保存着跟手指相关的信息,比如触摸的位置、时间、阶段
  • 当手指移动时,系统会更新同一个UITouch对象,使之能够一直保存该手指在的触摸位置
  • 当手指离开屏幕时,系统会销毁相应的UITouch对象
  • 提示:iPhone开发中,要避免使用双击事件!

UITouch的属性

  • 触摸产生时所处的窗口

@property(nonatomic,readonly,retain) UIWindow    *window;

  • 触摸产生时所处的视图

@property(nonatomic,readonly,retain) UIView      *view;

  • 短时间内点按屏幕的次数,可以根据tapCount判断单击、双击或更多的点击

@property(nonatomic,readonly) NSUInteger          tapCount;

  • 记录了触摸事件产生或变化时的时间,单位是秒

@property(nonatomic,readonly) NSTimeInterval      timestamp;

  • 当前触摸事件所处的状态

@property(nonatomic,readonly) UITouchPhase        phase;

UITouch的方法

- (CGPoint)locationInView:(UIView *)view;

返回值表示触摸在view上的位置

这里返回的位置是针对view的坐标系的(以view的左上角为原点(0, 0))

调用时传入的view参数为nil的话,返回的是触摸点在UIWindow的位置

- (CGPoint)previousLocationInView:(UIView *)view;

该方法记录了前一个触摸点的位置

UIEvent

  • 每产生一个事件,就会产生一个UIEvent对象
  • UIEvent:称为事件对象,记录事件产生的时刻和类型

常见属性

  • 事件类型

@property(nonatomic,readonly) UIEventType     type;

@property(nonatomic,readonly) UIEventSubtype  subtype;

  • 事件产生的时间

@property(nonatomic,readonly) NSTimeInterval  timestamp;

  • UIEvent还提供了相应的方法可以获得在某个view上面的触摸对象(UITouch)
  • 一次完整的触摸过程,会经历3个状态:
  1. 触摸开始:- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
  2. 触摸移动:- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
  3. 触摸结束:- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
  4. 触摸取消(可能会经历):- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event
  • 4个触摸事件处理方法中,都有NSSet *touches和UIEvent *event两个参数
  • 一次完整的触摸过程中,只会产生一个事件对象,4个触摸方法都是同一个event参数
  • 如果两根手指同时触摸一个view,那么view只会调用一次touchesBegan:withEvent:方法,touches参数中装着2个UITouch对象
  • 如果这两根手指一前一后分开触摸同一个view,那么view会分别调用2次touchesBegan:withEvent:方法,并且每次调用时的touches参数中只包含一个UITouch对象
  • 根据touches中UITouch的个数可以判断出是单点触摸还是多点触摸

然后用上述4个方法做了一个涂鸦app

很简单,先自定义一个view

@interface YUView : UIView
- (void)clear;
- (void)back;
@end

两个方法供控制器调用,重置和回退

@interface YUView ()
@property (nonatomic, strong) NSMutableArray *totalLines;
@end

私有属性是个可变数组,里面装画过的所有线的路径

实现代码如下

@implementation YUView

- (NSMutableArray *)totalLines {

    if (_totalLines == nil) {

        _totalLines = [NSMutableArray array];

    }

    return _totalLines;

}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [touches anyObject];

    CGPoint point = [touch locationInView:touch.view];

    UIBezierPath *currentPath = [UIBezierPath bezierPath];

    [currentPath moveToPoint:point];

    [self.totalLines addObject:currentPath];

    [self setNeedsDisplay];

}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    UITouch *touch = [touches anyObject];

    CGPoint point = [touch locationInView:touch.view];

    UIBezierPath *path = [self.totalLines lastObject];

    [path addLineToPoint:point];

    [self setNeedsDisplay];

}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {

    [self touchesMoved:touches withEvent:event];

}

- (void)drawRect:(CGRect)rect {

    [[UIColor blueColor] set];

    for (UIBezierPath *path in self.totalLines) {

        path.lineWidth = 5;

        [path stroke];

    }

}

- (void)clear {

    [self.totalLines removeAllObjects];

    [self setNeedsDisplay];

}

- (void)back {

    [self.totalLines removeLastObject];

    [self setNeedsDisplay];

}

@end

很简单,只要在触摸事件中存入触摸的点画线就行, 通过 [self setNeedsDisplay];重绘页面

重置只需清空路径数组,回退只需删除数组中最后一个路径即可

之前一直看swift文档,实在是太无聊,于是乎我决定把这个涂鸦用swift重构一遍,如下

class YUView : UIView {

    var paths:[UIBezierPath] = []

    func back() {

        self.paths.removeLast()

        self.setNeedsDisplay()

    }

    func clear() {

        self.paths.removeAll()

        self.setNeedsDisplay()

    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {

        let touch = touches.first

        let point = touch?.locationInView(touch?.view)

        let currrentPath = UIBezierPath.init()

        currrentPath.moveToPoint(point!)

        self.paths.append(currrentPath)

        self.setNeedsDisplay()

    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {

        let touch = touches.first

        let point = touch?.locationInView(touch?.view)

        let path = self.paths.last

        path?.lineJoinStyle = .Round

        path?.lineCapStyle = .Round

        path!.addLineToPoint(point!)

        self.setNeedsDisplay()

    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {

        self.touchesMoved(touches, withEvent: event)

    }

    override func drawRect(rect: CGRect) {

        UIColor.init(red: 0, green: 0, blue: 1, alpha: 1).set()

        for path in self.paths {

            path.lineWidth = 8

            path.stroke()

        }

    }

}

感觉第一次用上swift我就喜欢上它了,代码简洁而且对于我这样非常熟悉.语法的Java程序员非常亲切~

2015/11/27

Day 42

今天做了个手势解锁的页面

每个圆圈都是一个button通过改变状态改变图片,通过触摸事件画线就行了。

button最好别直接用UIButton,自己定义

@interface YUCircleView : UIButton

@end

@implementation YUCircleView

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self == [super initWithCoder:aDecoder]) {
        [self setup];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self == [super initWithFrame:frame]) {
       [self setup];
    }
    return self;
}

- (void) setup {
    self.userInteractionEnabled = NO;
    [self setImage:[UIImage imageNamed:@"gesture_node_normal"] forState:UIControlStateNormal];
    [self setImage:[UIImage imageNamed:@"gesture_node_highlighted"] forState:UIControlStateSelected];
}
@end

重写那两个初始化方法使按钮不管什么方式创建都设置好图片,不能互动是为了取消按钮的高亮状态

把按钮放进自定义的view里

@interface YULockView ()
@property (nonatomic, strong) NSMutableArray *selectedViews;
@property (nonatomic, assign) CGPoint currentPoint;
@end

这两个私有属性,selectedViews里面保存被选中的按钮,currentPoint保存用户当前触摸的点

先把九个按钮加上去并且排布好,注意子控件的frame要在layoutSubviews方法中执行并且要调用[super layoutSubviews];

- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    if (self == [super initWithCoder:aDecoder]) {
        [self setup];
    }
    return self;
}

- (instancetype)initWithFrame:(CGRect)frame {
    if (self == [super initWithFrame:frame]) {
        [self setup];
    }
    return self;
}

- (void) setup {
    for (int i = 0; i < 9; i++) {
        YUCircleView *circleView = [YUCircleView buttonWithType:UIButtonTypeCustom];
        circleView.tag = i;
        [self addSubview:circleView];
    }
}

- (void)layoutSubviews {
    [super layoutSubviews];
    CGFloat viewH = 80;
    CGFloat viewW = 80;
    int totalcol = 3;

    for (int i = 0; i < self.subviews.count; i++) {
        YUCircleView *btn = self.subviews[i];
        CGFloat padding = (self.bounds.size.width - totalcol * viewW) / (totalcol + 1);
        CGFloat viewX = padding * (i % totalcol + 1) + i % totalcol * viewW;
        CGFloat viewY = padding * (i / totalcol + 1) + i / totalcol * viewW;
        btn.frame = CGRectMake(viewX, viewY, viewW, viewH);
    }
}

在处理触摸事件的四个方法中经常要得到用户当前触摸的点,以及得到用户触摸到的按钮这两个功能,把他们单独抽出来做为方法比较好

- (CGPoint)getTouchPoint:(NSSet<UITouch *> *)touches {
    UITouch *touch = [touches anyObject];
    CGPoint point = [touch locationInView:touch.view];
    self.currentPoint = point;
    return point;
}

- (YUCircleView *)getTouchBtn:(CGPoint)point {
    for (YUCircleView *btn in self.subviews) {
        CGFloat d = 50;
        CGFloat frameX = btn.center.x - d * 0.5;
        CGFloat frameY = btn.center.y - d * 0.5;
        if( CGRectContainsPoint(CGRectMake(frameX, frameY, d, d), point)) {
            return btn;
        }
    }
    return nil;
}

触碰到圆心周围才判定触碰到按钮

于是触摸事件的方法如下

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    CGPoint currentPoint = [self getTouchPoint:touches];
    YUCircleView *btn = [self getTouchBtn:currentPoint];
    if (btn && btn.selected == NO) {
        btn.selected = YES;
        [self.selectedViews addObject:btn];
    }
    [self setNeedsDisplay];
}

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    CGPoint currentPoint = [self getTouchPoint:touches];
    YUCircleView *btn = [self getTouchBtn:currentPoint];
    if (btn && btn.selected == NO) {
        btn.selected = YES;
        [self.selectedViews addObject:btn];
    }
    [self setNeedsDisplay];
}

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    for (YUCircleView *btn in self.selectedViews) {
        btn.selected = NO;
    }
    [self.selectedViews removeAllObjects];
    [self setNeedsDisplay];
}

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    [self touchesEnded:touches withEvent:event];
}

- (void)drawRect:(CGRect)rect {
    if (self.selectedViews.count == 0) return;
    [[UIColor colorWithRed:32/255.0 green:210/255.0 blue:254/255.0 alpha:0.5] set];
    UIBezierPath *path = [UIBezierPath bezierPath];
    for (int i = 0; i < self.selectedViews.count; i++) {
        YUCircleView *btn = self.selectedViews[i];
        if (i == 0) {
            [path moveToPoint:btn.center];
        } else {
            [path addLineToPoint:btn.center];
        }
    }
    [path addLineToPoint:self.currentPoint];
    path.lineCapStyle = kCGLineCapRound;
    path.lineJoinStyle = kCGLineJoinBevel;
    path.lineWidth = 8;
    [path stroke];
}

drawRect方法中只要遍历所有选中的按钮再将他们的圆心依次相连就可以了,最后再连到用户当前触摸的点

这个解锁页面在用户画完后要拿到用户刚才画的路径进行操作的。

如何得到用户所画的路径呢?

这时候,初始化各个按钮给按钮绑定的tag就派上用场了,把每个选中的按钮的tag依次串成字符串就是路径啦,一般这个路径是要传出去的,由别人来操作,所以最好使用代理模式

首先声明代理协议

@class YULockView;
@protocol YULockViewDelegate <NSObject>
@optional
- (void)lockView:(YULockView *)lockView didFinishPath:(NSString *)path;
@end

在YULockView中加入代理属性

@interface YULockView : UIView

@property(nonatomic, weak) IBOutlet id<YULockViewDelegate> delegate;

@end

加入IBOutlet是为了我方便的连线设置代理

在touchesEnded方法中通知代理

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    // 通知代理
    if ([self.delegate respondsToSelector:@selector(lockView:didFinishPath:)]) {
        NSMutableString *path = [NSMutableString string];
        for (YUCircleView *btn in self.selectedViews) {
            [path appendFormat:@"%d", (int)btn.tag];
        }
        [self.delegate lockView:self didFinishPath:path];
    }  

    for (YUCircleView *btn in self.selectedViews) {
        btn.selected = NO;
    }
    [self.selectedViews removeAllObjects];
    [self setNeedsDisplay];
}

然后让控制器实现代理方法

@interface ViewController () <YULockViewDelegate>

@end

@implementation ViewController

- (void)lockView:(YULockView *)lockView didFinishPath:(NSString *)path {
    NSLog(@"路径为:%@",path);
}

- (void)viewDidLoad {
    [super viewDidLoad];
}
@end

随便画了一下控制台打印如下

2015-11-28 22:37:12.537 手势解锁-OC[835:45566] 路径为:13456780

接下来就用swift重新写了一遍

首先是自定义的button

class YUCircleView:UIButton {
    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }

    func setup() {
        self.userInteractionEnabled = false;
        self.setImage(UIImage(named: "gesture_node_normal"), forState: .Normal)
        self.setImage(UIImage(named: "gesture_node_highlighted"), forState: .Selected)
    }
}

接下来是自定义view的代码

public protocol YULockViewDelegate : NSObjectProtocol{

    func didFinishPath(lockView:UIView,path:String)

}

class YULockView:UIView {
    weak var delegate:YULockViewDelegate?
    var selectedViews:[YUCircleView] = []
    var currentPoint:CGPoint = CGPointZero

    func getTouchPoint(touches: Set<UITouch>) -> CGPoint {
        let touch = touches.first
        let point = touch?.locationInView(touch?.view)
        self.currentPoint = point!
        return point!
    }  

    func getTouchBtn(point:CGPoint) -> YUCircleView? {
        for btn in self.subviews {
            let d:CGFloat = 50;
            let frameX = btn.center.x - d * 0.5;
            let frameY = btn.center.y - d * 0.5;
            if( CGRectContainsPoint(CGRectMake(frameX, frameY, d, d), point)) {
                return btn as? YUCircleView;
            }
        }
        return nil
    }

    override func drawRect(rect: CGRect) {
        if self.selectedViews.count == 0 {return}
        UIColor(colorLiteralRed: 32/255.0, green: 210/255.0, blue: 1.0, alpha: 0.5).set()
        let path = UIBezierPath.init()
        for var i = 0; i < self.selectedViews.count; i += 1 {
            let btn = self.selectedViews[i]
            if i == 0 {
                path.moveToPoint(btn.center)
            } else {
                path.addLineToPoint(btn.center)
            }
        }
        path.addLineToPoint(self.currentPoint)
        path.lineCapStyle = .Round;
        path.lineJoinStyle = .Bevel;
        path.lineWidth = 8;
        path.stroke()
    }

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let point = self.getTouchPoint(touches)
        let btn = self.getTouchBtn(point)
        if (btn != nil) && (btn!.selected == false) {
            btn!.selected = true
            self.selectedViews.append(btn!)
        }
        self.setNeedsDisplay()
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        let point = self.getTouchPoint(touches)
        let btn = self.getTouchBtn(point)
        if (btn != nil) && (btn!.selected == false) {
            btn!.selected = true
            self.selectedViews.append(btn!)
        }
        self.setNeedsDisplay()
    }

    override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if ((self.delegate?.respondsToSelector(Selector.init("didFinishPath:”))) != nil) {
            var path = ""
            for btn in self.selectedViews {
                path += "\(btn.tag)"
            }
            self.delegate?.didFinishPath(self, path: path)
        }
        for item in self.selectedViews {
            item.selected = false
        }
        self.selectedViews.removeAll()
        self.setNeedsDisplay()
    }

    override func touchesCancelled(touches: Set<UITouch>?, withEvent event: UIEvent?) {
        self.touchesEnded(touches!, withEvent: event)
    } 

    override init(frame: CGRect) {
        super.init(frame: frame)
        self.setup()
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        self.setup()
    }

    func setup() {
        for var i = 0; i < 9; i += 1 {
            let btn = YUCircleView(type: .Custom)
            btn.tag = i
            self.addSubview(btn)
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        let viewH:CGFloat = 80
        let viewW:CGFloat = 80
        let totalcol:Int = 3
        for var i = 0; i < self.subviews.count; i += 1 {
            let col = i % totalcol
            let row = i / totalcol
            let paddingX = (self.bounds.size.width - CGFloat(totalcol)  * viewW) / CGFloat(totalcol + 1)
            let paddingY = paddingX
            let viewX = paddingX + CGFloat(col) * (viewW + paddingX)
            let viewY = paddingY + CGFloat(row) * (viewH + paddingY)
            let btn = self.subviews[i] as! YUCircleView
            btn.frame = CGRectMake(viewX, viewY, viewW, viewH)
        }
    }
}

  总体来说思路是一样的,只是代码语法以及风格不同,个人偏爱swift一点,但是swift管类型比较严,不同类型的数据不能做运算,于是在layoutSubviews()方法中转换类型费了点劲,接着就是设置代理和实现代理方法了

class ViewController: UIViewController, YULockViewDelegate{
    func didFinishPath(lockView: UIView, path: String) {
        print("路径为:"+path)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        for item in self.view.subviews {
            if item is YULockView {
                let lockView = item as! YULockView
                lockView.delegate = self
            }
        }
    }
}

随便画了一下控制台输出如下

路径为:840123675

时间: 2024-08-10 22:49:09

一个java程序员自学IOS开发之路(十)的相关文章

一个java程序员自学IOS开发之路(四)

根据上图,由于我是一个Java程序员,前面两个阶段还是学的比较快的,但是由于电脑配置不行,光是开启虚拟机登陆OS系统就卡的不要不要的了,在那里面写代码简直是煎熬= =,后面的UI学习又要启动ios模拟器,根本无法进行. 于是下定决心,入手一台Macbook pro,告别我用了四年的联想~今天本本到货啦,哈哈^_^,可以愉快的继续了 2015/10/14 Day 15 为了便于开发者打造各式各样的优秀app,UIKit框架提供了非常多功能强大又易用的UI控件 2015/10/16 Day 16 第

一个java程序员自学IOS开发之路(一)

首先自我介绍吧,南昌大学软件工程专业2015界毕业生,从大学牲变到程序猿,由于在学校里只学了Java语言和B/S架构开发,于是乎出来实习和工作也是搞Java网页开发. 但是作为一名果粉,现阶段想转IOS开发,最近也开始自学了,写点东西记下来吧 2015/9/17 Day 1 安装虚拟机并安装Mac OS X系统(苦逼的我还在用联想Y-470) 开始看C语言基础,由于大学里学过一点,还是比较轻松的 2015/9/19 Day 2 由于Java中没有指针,开始看指针的相关知识 2015/9/20 D

一个java程序员自学IOS开发之路(十四)

上个月实在是太忙了,在系统上线的前几天,业务人员还在不停的提新需求,真是醉了.上线那天晚上一直在出问题,熬到2点才搞定 2015/12/12 Day 47 今天开始学习网络编程 在移动互联网时代,移动应用,只有通过网络进行数据交互,才能保持活力!缺少了数据变化,无论多么华丽的应用,终将变成一潭死水 移动网络应用(良好的UI+良好的用户体验): 即时通讯:QQ 新闻:网易.凤凰新闻 视频:优酷.百度视频 音乐:虾米.QQ音乐 照片:Facebook.Flickr LBS(基于位置服务):高德.大众

一个java程序员自学IOS开发之路(十三)

2015/12/09 Day 46 今天学习多线程 多线程的优缺点 优点 充分发挥多核处理器优势,将不同线程任务分配给不同的处理器,真正进入“并行运算”状态 将耗时的任务分配到其他线程执行,由主线程负责统一更新界面会使应用程序更加流畅,用户体验更好 当硬件处理器的数量增加,程序会运行更快,而程序无需做任何调整 缺点 新建线程会消耗内存空间和CPU时间,线程太多会降低系统的运行性能 iOS的三种多线程技术 NSThread  使用NSThread对象建立一个线程非常方便 但是!要使用NSThrea

一个java程序员自学IOS开发之路(二)

2015/9/28 Day 8 最近工作上比较忙,加上虚拟机里mac把Xcode起来电脑就很卡了,更别提在虚拟机的mac系统里再开iPhone虚拟机了. 另外乘着中秋国庆好好休息下~过后准备大出血入手Macbook pro PS:同事居然在公司发的月饼里吃出来虫子= =,幸好我没打算吃,因为我讨厌月饼 2015/10/1 Day 9 开始学习OC内存管理 OC中的内存是要程序员来管的,因为并没有Java中的垃圾回收机制. 及时释放内存是我们要时刻考虑的,同时还是注意野指针 堆空间的对象需要手动代

一个java程序员自学IOS开发之路(八)

2015/11/8 Day 34 UITabBarController 跟UINavigationController类似,UITabBarController也可以轻松地管理多个控制器,轻松完成控制器之间的切换,典型例子就是QQ.微信等应用 UITabBarController的使用步骤 ? 初始化UITabBarController ? 设置UIWindow的rootViewController为UITabBarController ? 根据具体情况,通过addChildViewContro

一个java程序员自学IOS开发之路(六)

2015/10/28 Day 27 今天学习了即时通讯应用的UI布局,只是简单的利用UITableView展示数据 第一步 先利用storyboard把页面的框架搭起来 显示的数据是存在plist文件里的,所以要把他们转成模型 typedef enum { YUMessageTypeMe = 0, // 自己 YUMessageTypeOther // 其他人 }   YUMessageType; @interface YUMessage : NSObject @property (nonato

一个java程序员自学IOS开发之路(十一)

最近学习的进度慢了点,因为年底之前有个新项目要上线,而且每次业务人员过来一次,需求就有变动,于是不停的改改改= =!唉~不说了心好累 2015/11/29 Day 43 事件的产生和传递 发生触摸事件后,系统会将该事件加入到一个由UIApplication管理的事件队列中 UIApplication会从事件队列中取出最前面的事件,并将事件分发下去以便处理,通常,先发送事件给应用程序的主窗口(keyWindow) 主窗口会在视图层次结构中找到一个最合适的视图来处理触摸事件,这也是整个事件处理过程的

一个java程序员自学IOS开发之路(三)

  2015/10/10 Day 14 装箱和拆箱 数组和字典中只能存储对象类型,其他基本类型和结构体是没有办法放到数组和字典中的,当然你也是无法给它们发送消息的(也就是说有些NSObject的方法是无法调用的),这个时候通常会用到装箱(boxing)和拆箱(unboxing).其实各种高级语言基本上都有装箱和拆箱的过程,就像Java中有基本数据类型包装类 在ObjC中我们一般将基本数据类型装箱成NSNumber类型(当然它也是NSObject的子类,但是NSNumber不能对结构体装箱),调用