iOS开发——项目篇—高仿百思不得姐 05——发布界面、发表文字界面、重识 bounds、frame、scrollView
2015-09-10 16:32
561 查看
加号界面(发布模块)
一、点击加号modal出发布模块,创建控件,布局控件
1)使用xib加载view,如果在viewDidLoad创建控件并设置frame 那么self.view 的宽高 拿到的是xib的大小
2)如果在viewDidLayouSubviews布局子控件 那么self.view 的宽高 拿到的是屏幕的宽高(这里不推荐 最好在设置frame时 直接用屏幕宽高设置frame)
3)创建按钮,自定义按钮,布局按钮
二、添加动画
1)Core Animation
利用苹果自带的动画方法
动画只能作用在CALayer
无法监听到动画的中间值(frame值并不能改变 只是个假象)
2)pop
facebook出品的动画框架
动画能作用在任何对象
能监听到动画的中间值(真正的修改frame值)
3)示例程序
poping
LeamCube
github中搜索Animation
三、动画细节
1、 弹出动画(使用pop)
代码优化
2、退出动画
禁止用户的交互等小细节
点击按钮、取消按钮、屏幕三种不同情况
四、modal发段子等子控制器
1)选择正确的控制器去modal 选择的控制器不能是已经消亡的,一般用窗口的根控制器(此处根控制器为tabbarVC)
2)将跳转(发段子等功能)封装到一个block内,区分点击按钮、取消按钮、屏幕三种不同情况下有不同功能,也就是说点击按钮(发段子、发视频等)才需要有跳转的功能,其他两个不需要
三种不同情况
五、发段子界面
1)textView 默认会换行,但是没有占位文字,需自定义,封装成工具类、小框架
2)自定义带占位文字的textView
方法一 drawRect 画在一个矩形框内
.h
.m
方法二 添加label
.h
.m
3)如何去除占位文字
代理(不推荐)
通知 (参考上面代码)
4)设置占位文字颜色、字体、大小、普通内容、富文本内容、frame等属性
默认的情况下
重新设置的情况下(重写这五个属性的set方法,再重绘或者重新计算,frame重写layoutsubviews)
5)拖拽时取消编辑,退出键盘
设置竖直方向允许拖动,实现拖拽的代理方法控制退出键盘
6)设置导航栏的属性 字体颜色等(layouIfNeeded强制刷新,可解决因为设置属性而影响到状态)
六、三种刷新控件的方法
七、重识bounds、scrollView
1)bounds
bounds 指的是控件矩形框的位置和尺寸
bounds 是以自己内容(内部的子控件)的左上角为坐标原点
y = 正数 子控件会往上
y = 负数 子控件会往下
2)frame
frame 指的是控件矩形框的位置和尺寸
frame 是以自己父控件的左上角为坐标原点
3)bounds和frame的对比
以下图为例子
用绿色表示矩形框bounds(圈圈为坐标原点)
用红色表示矩形框frame
4)scrollView textView
当控制器中有超过两个scrollView(或textView)时,那么系统会在第一个添加的scrollView(或textView)顶部添加一定的偏移量,若有导航控制器,偏移64,若没有,偏移20
5)scrollView常用的属性
scrollView.contentSize; // 滚动范围(内容的尺寸)
scrollView.contentInset; // 内边距
scrollView.frame; // 以父控件内容的左上角为坐标原点,scrollView矩形框的位置和尺寸
scrollView.bounds; // 以自己内容的左上角为坐标原点,scrollView矩形框的位置和尺寸
scrollView.contentOffset; // 偏移量(scrollView.bounds.origin)
一、点击加号modal出发布模块,创建控件,布局控件
1)使用xib加载view,如果在viewDidLoad创建控件并设置frame 那么self.view 的宽高 拿到的是xib的大小
2)如果在viewDidLayouSubviews布局子控件 那么self.view 的宽高 拿到的是屏幕的宽高(这里不推荐 最好在设置frame时 直接用屏幕宽高设置frame)
3)创建按钮,自定义按钮,布局按钮
- (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.titleLabel.textAlignment = NSTextAlignmentCenter; self.titleLabel.font = [UIFont systemFontOfSize:15]; [self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal]; } return self; } - (void)layoutSubviews { [super layoutSubviews]; self.imageView.y = 0; self.imageView.centerX = self.width * 0.5; self.titleLabel.width = self.width; self.titleLabel.y = CGRectGetMaxY(self.imageView.frame); self.titleLabel.x = 0; self.titleLabel.height = self.height - self.titleLabel.y; }
二、添加动画
1)Core Animation
利用苹果自带的动画方法
动画只能作用在CALayer
无法监听到动画的中间值(frame值并不能改变 只是个假象)
2)pop
facebook出品的动画框架
动画能作用在任何对象
能监听到动画的中间值(真正的修改frame值)
// 动画 POPSpringAnimation *anim = [POPSpringAnimation animationWithPropertyNamed:kPOPViewFrame]; anim.fromValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonY - CHGScreenH, buttonW, buttonH)]; anim.toValue = [NSValue valueWithCGRect:CGRectMake(buttonX, buttonY, buttonW, buttonH)]; anim.springSpeed = 10; anim.springBounciness = 10; // CACurrentMediaTime()获得的是当前时间 anim.beginTime = CACurrentMediaTime() + [self.times[i] doubleValue]; [button pop_addAnimation:anim forKey:nil];
3)示例程序
poping
LeamCube
github中搜索Animation
三、动画细节
1、 弹出动画(使用pop)
代码优化
2、退出动画
禁止用户的交互等小细节
// 禁止交互 self.view.userInteractionEnabled = NO;
点击按钮、取消按钮、屏幕三种不同情况
四、modal发段子等子控制器
1)选择正确的控制器去modal 选择的控制器不能是已经消亡的,一般用窗口的根控制器(此处根控制器为tabbarVC)
2)将跳转(发段子等功能)封装到一个block内,区分点击按钮、取消按钮、屏幕三种不同情况下有不同功能,也就是说点击按钮(发段子、发视频等)才需要有跳转的功能,其他两个不需要
#pragma mark - 退出动画 - (void)exit:(void (^)())task { // 禁止交互 self.view.userInteractionEnabled = NO; // 让按钮执行动画 for (int i = 0; i < self.buttons.count; i++) { CHGPublishButton *button = self.buttons[i]; POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY]; anim.toValue = @(button.layer.position.y + CHGScreenH); // CACurrentMediaTime()获得的是当前时间 anim.beginTime = CACurrentMediaTime() + [self.times[i] doubleValue]; [button.layer pop_addAnimation:anim forKey:nil]; } // 让标题执行动画 POPBasicAnimation *anim = [POPBasicAnimation animationWithPropertyNamed:kPOPLayerPositionY]; anim.toValue = @(self.sloganView.layer.position.y + CHGScreenH); // CACurrentMediaTime()获得的是当前时间 anim.beginTime = CACurrentMediaTime() + [self.times.lastObject doubleValue]; CHGWeakSelf; [anim setCompletionBlock:^(POPAnimation *anim, BOOL finished) { [weakSelf dismissViewControllerAnimated:NO completion:nil]; // 可能会做其他事情 // if (task) task(); !task ? : task(); }]; [self.sloganView.layer pop_addAnimation:anim forKey:nil]; }
三种不同情况
#pragma mark - 点击 - (void)buttonClick:(XMGPublishButton *)button { [self exit:^{ // 按钮索引 NSUInteger index = [self.buttons indexOfObject:button]; switch (index) { case 2: { // 发段子 // 弹出发段子控制器 CHGPostWordViewController *postWord = [[CHGPostWordViewController alloc] init]; [self.view.window.rootViewController presentViewController:[[CHGNavigationController alloc] initWithRootViewController:postWord] animated:YES completion:nil]; break; } case 0: XMGLog(@"发视屏"); break; case 1: XMGLog(@"发图片"); break; default: XMGLog(@"其它"); break; } }]; } - (IBAction)cancel { [self exit:nil]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self exit:nil]; }
五、发段子界面
1)textView 默认会换行,但是没有占位文字,需自定义,封装成工具类、小框架
2)自定义带占位文字的textView
方法一 drawRect 画在一个矩形框内
.h
#import <UIKit/UIKit.h> @interface CHGPlaceholderTextView : UITextView /** 占位文字 */ @property (nonatomic, copy) NSString *placeholder; /** 占位文字颜色 */ @property (nonatomic, strong) UIColor *placeholderColor; @end
.m
#import "CHGPlaceholderTextView.h" @implementation CHGPlaceholderTextView - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { self.font = [UIFont systemFontOfSize:17]; self.textColor = [UIColor blackColor]; self.placeholderColor = [UIColor grayColor]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:self]; } return self; } - (void)textDidChange:(NSNotification *)note { // 会重新调用drawRect:方法 [self setNeedsDisplay]; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)drawRect:(CGRect)rect { // 如果有文字,就直接返回,不需要画占位文字 // if (self.text.length || self.attributedText.length) return; if (self.hasText) return; // 属性 NSMutableDictionary *attrs = [NSMutableDictionary dictionary]; attrs[NSFontAttributeName] = self.font; attrs[NSForegroundColorAttributeName] = self.placeholderColor; rect.origin.x = 5; rect.origin.y = 8; rect.size.width -= 2 * rect.origin.x; [self.placeholder drawInRect:rect withAttributes:attrs]; } // 若是不写 进入发表界面 占位文字不能随textView上下滚动 - (void)layoutSubviews { [super layoutSubviews]; [self setNeedsDisplay]; } #pragma mark - setter - (void)setPlaceholderColor:(UIColor *)placeholderColor { _placeholderColor = placeholderColor; [self setNeedsDisplay]; } - (void)setPlaceholder:(NSString *)placeholder { _placeholder = placeholder; [self setNeedsDisplay]; } - (void)setFont:(UIFont *)font { [super setFont:font]; [self setNeedsDisplay]; } - (void)setText:(NSString *)text { [super setText:text]; [self setNeedsDisplay]; } - (void)setAttributedText:(NSAttributedString *)attributedText { [super setAttributedText:attributedText]; [self setNeedsDisplay]; } @end
方法二 添加label
.h
#import <UIKit/UIKit.h> @interface CHGPlaceholderTextView2 : UITextView /** 占位文字 */ @property (nonatomic, copy) NSString *placeholder; /** 占位文字颜色 */ @property (nonatomic, strong) UIColor *placeholderColor; @end
.m
#import "CHGPlaceholderTextView2.h" @interface CHGPlaceholderTextView2 () /** 占位文字label */ @property (nonatomic, weak) UILabel *placeholderLabel; @end @implementation CHGPlaceholderTextView2 - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { // 创建label UILabel *placeholderLabel = [[UILabel alloc] init]; placeholderLabel.numberOfLines = 0; [self addSubview:placeholderLabel]; self.placeholderLabel = placeholderLabel; // 设置默认字体 self.font = [UIFont systemFontOfSize:15]; // 设置默认颜色 self.placeholderColor = [UIColor grayColor]; // 使用通知监听文字改变 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textDidChange:) name:UITextViewTextDidChangeNotification object:self]; } return self; } - (void)textDidChange:(NSNotification *)note { self.placeholderLabel.hidden = self.hasText; } - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)layoutSubviews { [super layoutSubviews]; self.placeholderLabel.x = 5; self.placeholderLabel.y = 8; self.placeholderLabel.width = self.width - 2 * self.placeholderLabel.x; [self.placeholderLabel sizeToFit]; } #pragma mark - setter - (void)setPlaceholder:(NSString *)placeholder { _placeholder = [placeholder copy]; self.placeholderLabel.text = placeholder; [self.placeholderLabel sizeToFit]; // [self setNeedsLayout]; } - (void)setPlaceholderColor:(UIColor *)placeholderColor { _placeholderColor = placeholderColor; self.placeholderLabel.textColor = placeholderColor; } - (void)setFont:(UIFont *)font { [super setFont:font]; self.placeholderLabel.font = font; [self.placeholderLabel sizeToFit]; // [self setNeedsLayout]; } - (void)setText:(NSString *)text { [super setText:text]; self.placeholderLabel.hidden = self.hasText; } - (void)setAttributedText:(NSAttributedString *)attributedText { [super setAttributedText:attributedText]; self.placeholderLabel.hidden = self.hasText; } @end
3)如何去除占位文字
代理(不推荐)
通知 (参考上面代码)
4)设置占位文字颜色、字体、大小、普通内容、富文本内容、frame等属性
默认的情况下
重新设置的情况下(重写这五个属性的set方法,再重绘或者重新计算,frame重写layoutsubviews)
5)拖拽时取消编辑,退出键盘
设置竖直方向允许拖动,实现拖拽的代理方法控制退出键盘
6)设置导航栏的属性 字体颜色等(layouIfNeeded强制刷新,可解决因为设置属性而影响到状态)
六、三种刷新控件的方法
// 重新刷新自己和子控件的所有内容(状态、尺寸) [tempView layoutIfNeeded]; // 重新调用tempView的layoutSubviews(重新排布子控件的frame) [tempView setNeedsLayout]; // 重新调用tempView的drawRect:方法(重新绘制tempView里面的内容,一般不包括子控件) [tempView setNeedsDisplay];
七、重识bounds、scrollView
1)bounds
bounds 指的是控件矩形框的位置和尺寸
bounds 是以自己内容(内部的子控件)的左上角为坐标原点
y = 正数 子控件会往上
y = 负数 子控件会往下
2)frame
frame 指的是控件矩形框的位置和尺寸
frame 是以自己父控件的左上角为坐标原点
3)bounds和frame的对比
以下图为例子
用绿色表示矩形框bounds(圈圈为坐标原点)
用红色表示矩形框frame
4)scrollView textView
当控制器中有超过两个scrollView(或textView)时,那么系统会在第一个添加的scrollView(或textView)顶部添加一定的偏移量,若有导航控制器,偏移64,若没有,偏移20
self.automaticallyAdjustsScrollViewInsets = NO; // 当你有超过1个scrollView的时候,建议你设置self.automaticallyAdjustsScrollViewInsets = NO;,然后自己根据需要去调整scrollView的inset
5)scrollView常用的属性
scrollView.contentSize; // 滚动范围(内容的尺寸)
scrollView.contentInset; // 内边距
scrollView.frame; // 以父控件内容的左上角为坐标原点,scrollView矩形框的位置和尺寸
scrollView.bounds; // 以自己内容的左上角为坐标原点,scrollView矩形框的位置和尺寸
scrollView.contentOffset; // 偏移量(scrollView.bounds.origin)
相关文章推荐
- iOS开发中@selector的理解
- iOS中自动消失提示框的实现
- ios推送到某个界面的方法
- iOS 5.1.1 设备不能安装AdHoc问题版本号
- IOS委托设计模式(摘自IOS开发指南)
- iOS平台游戏安全之IPA破解原理及防御
- iOS 自定义scrollView的pagingEnabled
- iOS项目更新之升级Xcode7 & iOS9
- iOS项目更新之升级Xcode7 & iOS9
- CALayer4-自定义层
- CALayer3-层的属性
- CALayer2-创建新的层
- CALayer1-简介
- iOS开发 textField 键盘遮挡问题
- 利用iOS8新特性实现毛玻璃效果
- 关于友盟iOS推送的随笔
- ios中NULL nil Nil的区别
- iOS开发--BaseModel
- iOS开发 __给文本添加行间距 如Lable的Text
- nagios与sendEmail结合实现邮件报警