从这节课开始我们学习搭建发送微博界面。发送界面看起来简单,但是却包含了许多细节处理。所以我们分为几节课来完成,尽量讲解详细点。

本节内容
第十六节代码资料

本节代码资料
16.1 设置发送界面的导航内容
当我们点击中间加号按钮的时候,微博会弹出一个发送界面,然后才可以编辑。界面效果如下:

%title插图%num
开发之前我们先罗列出界面的几个细节:

1 导航条的字体颜色是橘色,但“发送”按钮一开时是灰色,且不能点击,只有当用户输入文字后,才能恢复。
2 输入文本框有占位符“分享新鲜事…”,且占位符的字体大小应该与输入的文字大小相等。
3 当用户点击输入文字的时候,占位符消失。
4 刚进入发送界面时,键盘是自动弹出的,如果拖拽文本输入框,键盘就会消失。
下面我们根据以上这些要求,一步一步的去完成设置。
首先,创建一个YGComposeViewController,继承自UIViewController。我们想在YGTabBarController内监听加号按钮的点击,当其被点击时,弹出发送界面。这里就需要使用代理方法,因为之前YGTabBarController就已经遵守了YGTabBar 的代理,所以我们就之前的代理内再添加一个方法。

– (void)tabBarDidClickPlusButton:(YGTabBar *)tabBar;
1
然后在YGTabBar内创建plus Button内的方法中监听按钮的点击:

[btn addTarget:self action:@selector(plusClick) forControlEvents:UIControlEventTouchUpInside]
1
点击加号按钮时调用此方法:

#pragma mark – 点击加号按钮时调用
– (void)plusClick
{
// 弹出控制器
if ([_delegate respondsToSelector:@selector(tabBarDidClickPlusButton:)]) {
[_delegate tabBarDidClickPlusButton:self];
}
}

*后我们再YGTabBarController内实现代理:

-(void)tabBarDidClickPlusButton:(YGTabBar *)tabBar
{
// 创建发送微博控制器
YGComposeViewController *composeVc = [[YGComposeViewController alloc] init];
YGNavigationController *nav = [[YGNavigationController alloc] initWithRootViewController:composeVc];

[self presentViewController:nav animated:YES completion:nil];
}

因为我们还要设置发送界面的导航条字体颜色,所以这里直接用我们之前自定义的导航条(应该没忘吧)。
此时运行项目,点击加号按钮,就会看到一个黑色的界面显示出来了。为了美观,也为了让导航条的运动不那么明显,这里把控制器背景颜色设置成白色。然后我们在view DidLoad中设置导航条内容,代码如下:

– (void)setUpNavgationBar
{
self.title = @”发微博”;

// left
self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@”取消” style:0 target:self action:@selector(dismiss)];

// right
UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
[btn setTitle:@”发送” forState:UIControlStateNormal];
[btn setTitleColor:[UIColor orangeColor] forState:UIControlStateNormal];
[btn setTitleColor:[UIColor lightGrayColor] forState:UIControlStateDisabled];
[btn sizeToFit];
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
rightItem.enabled = NO;
self.navigationItem.rightBarButtonItem = rightItem;

}

本来导航条的右边按钮的设置方法是跟左边按钮一样的,但是我们试过之后发现,全局导航条不能用文字属性设置disable情况下的颜色,所以这里只能使用一个新的UIButton来设置了。
[TMD,我这里插播一句话,估计那些没经过我同意就复制我微博的人也不会看到。没经过我同意就转发我微博的那些网站竟然把时间调到比我原创微博还早半天。其它我都能忍,这我忍不了啊,搞得像我是在抄袭一样。所以这里我声明,我在2016年1月31号凌晨一点发布了此博客,其它都是转载]

16.2 自定义文本输入框textView
首先跟大家解释下UITextView和UITextField两者的不同。
两者*大的区别是:
1、UITextView支持多行输入并且可以滚动显示浏览全文,而UITextField只能单行输入。
2、UITextView继承自UIScrollView,UITextField继承自UIView[UIControl]。
3、UITextview没有placeholder属性 UItextField有placeholder属性
所以这里我们选择UITextView但是要添加一个UILabel子控件,用来显示占位符。
新建YGComposeTextView继承自UITextView,因为我们要让外部可以修改占位符,所以在其头文件中添加一个placeHolder (NSString)属性。
在composeTextView中懒加载一个placeHolderLabel,代码如下:

– (UILabel *)placeHolderLabel
{
if (_placeHolderLabel == nil) {

UILabel *label = [[UILabel alloc] init];

[self addSubview:label];

_placeHolderLabel = label;

}

return _placeHolderLabel;
}

懒加载的意思就是,当控件有值的时候就创建,没有就不创建,跟在init中添加是不一样的。
重载setPlaceHolder方法:

– (void)setPlaceHolder:(NSString *)placeHolder
{
_placeHolder = placeHolder;

self.placeHolderLabel.text = placeHolder;
// label的尺寸跟文字一样
[self.placeHolderLabel sizeToFit];
}

然后将YGComposeViewController内添加YGComposeTextView。 代码如下:

#pragma mark – 添加textView
– (void)setUpTextView
{
YGComposeTextView *textView = [[YGComposeTextView alloc] initWithFrame:self.view.bounds];
_textView = textView;
// 设置占位符
textView.placeHolder = @”abc”;
[self.view addSubview:textView];
}

但是这时候运行项目就会发现,占位符的字体和位置,与输入的文字不一样,如下图,所以我们首先要设置字体大小:

我们在初始化textView时设置其字体:

– (instancetype)initWithFrame:(CGRect)frame
{
if (self = [super initWithFrame:frame]) {
self.font = [UIFont systemFontOfSize:13];
}
return self;
}

然后再重写setFont方法,让占位符的字体大小与文本框的字体大小相同:

– (void)setFont:(UIFont *)font
{
[super setFont:font];

self.placeHolderLabel.font = font;
[self.placeHolderLabel sizeToFit];
}

字体大小解决后,就可以解决占位符的位置了,重写layOutSubviews方法:

– (void)layoutSubviews
{
[super layoutSubviews];

self.placeHolderLabel.x = 5;
self.placeHolderLabel.y = 8;
}

16.3 输入时隐藏占位符
自定义textView还有*后*后一个功能要完成,就是在输入文字的时候自动隐藏占位符。这里采用通知的方法:

// 监听文本框的输入
/**
* Observer:谁需要监听通知
* name:监听的通知的名称
* object:监听谁发送的通知,nil:表示谁发送我都监听
*
*/
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(textChange) name:UITextViewTextDidChangeNotification object:nil];

当监听到文本框文字变化时,执行textChange方法:

– (void)textChange
{
// 判断下textView有木有内容
if (_textView.text.length) { // 有内容
_textView.hidePlaceHolder = YES;
}else{
_textView.hidePlaceHolder = NO;
}
}

在这里别忘了给YGComposeTextView添加一个BOOL类型的属性,表明外界要传递给它一个是否隐藏placeHolder的信息,以便外部控制里面的内容。
然后重写setHidePlaceHolder:

– (void)setHidePlaceHolder:(BOOL)hidePlaceHolder
{
_hidePlaceHolder = hidePlaceHolder;

self.placeHolderLabel.hidden = hidePlaceHolder;

}

*后别忘了移除通知:

– (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}

16.4 自动弹出键盘 与隐藏键盘
这个功能应该是比较基础的内容了,首先在一开始就让键盘自动弹出:

– (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];

[_textView becomeFirstResponder];

}

然后在拖拽UITextView的时候,自动隐藏键盘。用到的方法就是让YGComposeViewController执行UITextView 的代理方法,因为UITextView的只有在内容超过大小的时候才能拖拽,所以不要忘了在setUpTextView内设置textView允许一直可以拖拽

// 默认允许垂直方向拖拽

代理方法如下:

#pragma mark – 开始拖拽的时候调用
– (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
[self.view endEditing:YES];
}

因为细节处理比较多,这节课就到这里吧,请自己主动敲代码哦。动手与不动手对开发过程的理解差别很大的。下节课将会讲解如何设置键盘上方的发送的工具栏,然后发送文字微博。