加号界面(发布模块)

一、点击加号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:];
[self setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];
}
return self;
} - (void)layoutSubviews
{
[super layoutSubviews]; self.imageView.y = ;
self.imageView.centerX = self.width * 0.5; self.titleLabel.width = self.width;
self.titleLabel.y = CGRectGetMaxY(self.imageView.frame);
self.titleLabel.x = ;
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 = ;
anim.springBounciness = ;
// 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 = ; 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 : { // 发段子
// 弹出发段子控制器
CHGPostWordViewController *postWord = [[CHGPostWordViewController alloc] init];
[self.view.window.rootViewController presentViewController:[[CHGNavigationController alloc] initWithRootViewController:postWord] animated:YES completion:nil];
break;
} case :
XMGLog(@"发视屏");
break; case :
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:]; 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 = ;
rect.origin.y = ;
rect.size.width -= * 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 = ;
[self addSubview:placeholderLabel];
self.placeholderLabel = placeholderLabel; // 设置默认字体
self.font = [UIFont systemFontOfSize:]; // 设置默认颜色
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 = ;
self.placeholderLabel.y = ;
self.placeholderLabel.width = self.width - * 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开发——项目篇—高仿百思不得姐 05——发布界面、发表文字界面、重识 bounds、frame、scrollView的更多相关文章

  1. iOS开发——项目篇—高仿百思不得姐

    01 一.包装为导航控制器 UINavigationController *nav = [[UINavigationController alloc] initWithRootViewControll ...

  2. iOS开发:一个高仿美团的团购ipad客户端的设计和实现(功能:根据拼音进行检索并展示数据,离线缓存团购数据,浏览记录与收藏记录的批量删除等)

    大致花了一个月时间,利用各种空闲时间,将这个客户端实现了,在这里主要是想记录下,设计的大体思路以及实现过程中遇到的坑...... 这个项目的github地址:https://github.com/wz ...

  3. iOS开发UI篇—Quartz2D简单使用(二)

    iOS开发UI篇—Quartz2D简单使用(二) 一.画文字 代码: // // YYtextview.m // 04-写文字 // // Created by 孔医己 on 14-6-10. // ...

  4. iOS开发拓展篇——如何把项目托管到GitHub

    iOS开发拓展篇——如何把项目托管到GitHub 说明:本文主要介绍如何把一个OC项目托管到Github,重操作轻理论. 第一步:先注册一个Github的账号,这是必须的 注册地址:Github官网注 ...

  5. iOS开发多线程篇 05 —GCD介绍

    iOS开发多线程篇—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 G ...

  6. iOS开发网络篇—简单介绍ASI框架的使用

    iOS开发网络篇—简单介绍ASI框架的使用 说明:本文主要介绍网络编程中常用框架ASI的简单使用. 一.ASI简单介绍 ASI:全称是ASIHTTPRequest,外号“HTTP终结者”,功能十分强大 ...

  7. iOS开发UI篇—CAlayer(创建图层)

    iOS开发UI篇—CAlayer(创建图层) 一.添加一个图层 添加图层的步骤: 1.创建layer 2.设置layer的属性(设置了颜色,bounds才能显示出来) 3.将layer添加到界面上(控 ...

  8. iOS开发数据库篇—SQLite简单介绍

    iOS开发数据库篇—SQLite简单介绍 一.离线缓存 在项目开发中,通常都需要对数据进行离线缓存的处理,如新闻数据的离线缓存等. 说明:离线缓存一般都是把数据保存到项目的沙盒中.有以下几种方式 (1 ...

  9. iOS开发UI篇—iOS开发中三种简单的动画设置

    iOS开发UI篇—iOS开发中三种简单的动画设置 [在ios开发中,动画是廉价的] 一.首尾式动画 代码示例: // beginAnimations表示此后的代码要“参与到”动画中 [UIView b ...

随机推荐

  1. TestLink安装及整合Jira

    TestLink安装及整合Jira 1.Testlink 安装部署 Testlink是一个开源的测试管理工具,主要用于管理测试用例,从测试需求.测试计划.测试用例管理和用例执行,到最后的结果分析,一套 ...

  2. hadoop对于压缩文件的支持及算法优缺点

    hadoop对于压缩文件的支持及算法优缺点   hadoop对于压缩格式的是透明识别,我们的MapReduce任务的执行是透明的,hadoop能够自动为我们 将压缩的文件解压,而不用我们去关心. 如果 ...

  3. 创建一个jQuery UI的垂直进度条效果

    日期:2013-9-24  来源:GBin1.com 在线演示 缺省的jQuery UI只有水平的进度条效果,没有垂直的进度条效果,仅仅重新定义JQuery UI的CSS不能解决这个问题. 这里我们扩 ...

  4. Thread.interrupt()方法理解

    原博客地址: 多线程编程 实战篇 (四) 不客气地说,至少有一半人认为,线程的"中断"就是让线程停止. 如果你也这么认为,那你对多线程编程还没有入门. 在java中,线程的中断(i ...

  5. 自学Zabbix3.6.5-触发器item-Unit symbols单位符号

    在zabbix里面,我们不需要使用大数字来,例如我们可以不使用86400来表示一天,这个数字又不容易理解也容易出错.用什么办法来解决大数字问题呢?我们可以使用单位来简化,例如简化zabbix触发器表达 ...

  6. Eclipse安装svn插件的几种方式 转帖....

    Eclipse安装svn插件的几种方式 1.在线安装: (1).点击 Help --> Install New Software... (2).在弹出的窗口中点击add按钮,输入Name(任意) ...

  7. markdown文本转换word,pdf

    pandoc及下载和安装 pandoc是什么 pandoc是一个软件,是一个能把千奇百怪的文档格式互相转换的神器,是一把文档转换的瑞士军刀(swiss-army knife).不多说,放一张其官网(h ...

  8. 【BZOJ2111】[ZJOI2010]排列计数(组合数学)

    [BZOJ2111][ZJOI2010]排列计数(组合数学) 题面 BZOJ 洛谷 题解 就是今年九省联考\(D1T2\)的弱化版? 直接递归组合数算就好了. 注意一下模数可以小于\(n\),所以要存 ...

  9. BZOJ 4764: 弹飞大爷

    4764: 弹飞大爷 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 4  Solved: 4[Submit][Status][Discuss] Des ...

  10. LDA理解

    LDA只是一个求解思路. 1.理解LDA首先要理解EM算法,EM不能叫做一个算法,只是一个思想:它要求解的其实是一个极大似然估计,就是我用已知量去求解导致这个已知量出现的最大概率,而在这里又恰恰有点偏 ...