1 项目第二天
2
3 1.需求:
4
5 设置UITabBar 上按钮内容 => UITabBar上按钮内容对应的子控制器的tabBarItem (模型)决定
6
7 - tabBarController 的第0个子控制是导航控制器
8 - 如果想通过导航控制器的根控制器来设置tabBarItem上的内容:必须先设置图片,文字才能显示
9 - 所以建议在导航控制器中设置tabBarItem 的内容
10 2.设置UITabBar上按钮内容出现的问题
11
12 选中按钮图片被渲染
13
17 - 解决
18 //这个方法可设置图片保持原始样式,注意是对象方法
19 //注意2:返回一个没有被渲染的图片
20 image = [[[UIImage alloc]init]imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
21
22 //在这里我们用得比较多,所以给UIImage 加一个分类最好
23 //你给我一个图片名,我给你一张没渲染过的图片
24 + (UIImage *)imageNameRenderOriginal:(NSString *)imageName;
25
26 //实现
27 + (UIImage *)imageNameRenderOriginal:(NSString *)imageName
28 {
29 UIImage *image = [UIImage ImageName:imageName];
30 image = [image imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];
31 return image;
32 }
33 补充
34
35 怎么扩充插件
36 目的:让分类方法也有图片名称提示
37 思路:查到插件=>插件安装到电脑=>在电脑某个文件下=>如何寻找这个文件=>找到插件代码,执行插件代码,自动安装插件 =>install
38 打开你之前运行的插件工程
39 在X-code 左侧栏找到放大镜.在里面搜索:install
40 有一个安装路径:那就是你插件安装位置,就到里面修改plist 文件(复制一份,把你要扩充的内容粘贴上去,替代之前复制出来的内容)
41 选中按钮文字被渲染,文字要改大一些
42
43 思考:选中按钮是由UITabBarItem决定的,首先我们先要进入它的头文件找有没titleColor 相关的属性 =>发现没有 => 进它父类(UIBarItem)的属性找有没找到(command + F search :color) =>有一个text Color ==>对应方法:- (void)setTitleTextAttributes:(nullable NSDictionary *)attributes forState:(UIControlState)state
44 TextAttributes :富文本属性(设置文字颜色,字体.阴影.图文混排```)
45
46 /*
47 1参:传一个字典:根据字典设置属性
48 2参:属性在显示的状态
49 */
50 - (void)setTitleTextAttributes:(nullable NSDictionary<NSString *,id> *)attributes forState:(UIControlState)state
51
52 //使用:
53 - 分析:我们是需要设置所有的UITabBarItem 的标题颜色及属性都成一个样,所以想到统一设置(appearance):对比下面两种方法后:在load方法中写更合适
54 - 认识:load/initialize
55 //当程序启动时,把所有类加载在内存时调用.只调用一次
56 + (void)load
57 {
58 //获取UITabBarItem外观
59 UITabBarItem *item = [UITabBarItem appearance];
60
61 // 创建文字属性字典描述文字属性
62 NSMutableDictionary *attr = [NSMutableDictionary dictionary];
63
64 // 颜色
65 attr[NSForegroundColorAttributeName] = [UIColor blackColor];
66
67 // 设置按钮文字颜色
68 [item setTitleTextAttributes:attr forState:UIControlStateSelected];
69 }
70 //第一次使用当前类或者子类时调用/初始化类--可能不止调用一次
71 + (void)initialize
72 {
73
74 }
75 补充:
76
77 怎么知道TextAttributes有哪些key :
78
79 在UITabBarItem /父类的 textColor 方法中已经说明:using the keys found in NSAttributedString.h. (在这个头文件中找,里面也说明key 对应的value )
80 注意点:UIControlStateSelected 状态下设置文字大小是无效的/设置文字大小必须在正常状态
81 关于appearance
82
83 并不是所有类都可以调用这个方法:
84 前提:本身/或父类遵守了这个协议:UIAppearance
85 并不是遵守了这个协议所有的属性都可以设置 ==>在属性或方法后面要有:UI_APPEARANCE_SELECTOR(这个宏)
86 因为UIView已经遵守了这个协议,所以所有的控件都有这个方法(appearance)/方法能不能全局设置==>看有没:UI_APPEARANCE_SELECTOR(这个宏)
87 只要通过appearance 设置属性:必须要在显示之前设置
88 tintColor:可以设置默认渲染颜色:在把TabBarItem 上的所以Item颜色都设置成为黑色.
89 self.tabBar.tintColor = [UIColor blackColor];
90 中间在按钮不显示
91
92 观察图片尺寸:(49 *49) == tabBar 的高度==>图片太大/系统默认渲染
93
94 位置不对==>找有没什么方法可设置图片的fame 相关 ==>进入UITabBarItem 头文件==>没有==> 进入父类头文件==>有一个imageInsets ==> top:7 bottom :-7 ==效果可以 ==>还有问题:样品中按钮并不是点中状态,而是高亮状态 ==>手指不点时是正常状态 ==>系统的Item没有高亮状态这个属性 ==>这个按钮你只能用UIButton做,不能用系统的Item.
95
96 //实现:
97 1.控件我们一般用的是懒加载
98 @property (nonatomic, weak) UIButton *plusButton
99
100
101 - (UIButton *)plusButton
102 {
103 if (!_plusButton) {
104 //局部变量默认就是强指针(在大括号没结束)
105 UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
106 [btn setImage:[UIImage imageNamed:@"tabBar_publish_icon"] forState:UIControlStateNormal];
107 [btn setImage:[UIImage imageNamed:@"tabBar_publish_click_icon"] forState:UIControlStateHighlighted];
108
109 //设置尺寸(自适应:内容多大,按钮就多大)
110 [btn sizeToFit];
111
112 //添加到tabBar 上
113 [self.tabBar addSubview:btn];
114
115 _plusButton = btn;
116 }
117 return _plusButton
118
119 }
120
121 //可在viewDidload 方法中加载
122 - (void)viewDidload
123 {
124 [super viewDidLoad];
125
126 //注意点:不能写成 self.plusButton.center = self.tabBar.center ==>因为center是以父控件左上角为参照,而他们俩不是同一个父控件(center = position)
127
128 self.plusButton.center = CGPointMake(self.tabBar.bounds.size.width * 0.5 ,self.tabBar.bounds.size.height * 0.5);
129
130 //但设置完后==>plusButton不能点击==>看小面包后发现==>UITabBarItem的小按钮在前面==>
131 //因为UITabBarItem按钮是在viewWillAppear中加载的.是view加载完毕后才加载的,所以item在上面==>
132 //要想办到btn 能点击:
133 1.设置vc.tabBarItem.enabled = NO;
134 或 2.在 viewWillAppear 执行完毕后再:
135 self.plusButton.center = CGPointMake(self.tabBar.bounds.size.width * 0.5 ,self.tabBar.bounds.size.height * 0.5);
136 }
137 3.给UIView抽一个分类(frame)
138
139 注意点:
140 为了以后在公司的开发中避免分类冲突,分类名及定义的属性最好加上自己的前缀
141 - 如:
142 - (void)setPJ_height:(CGFloat)PJ_height
143 {
144 CGRect frame = self.frame;
145 frame.size.height = PJ_height;
146 self.frame = frame;
147 }
148
149 - (CGFloat)PJ_height
150 {
151 return self.frame.size.height;
152 }
153 4.PCH
154
155 注意点
156 PCH 的名字和工程名字要一样
157 创建好PCH后还要配置路径
158
159
160 不可点击进去看的宏在哪里设置
161
162 调试阶段的设置
163
164 #ifdef DEBUG // 调试
165
166 #define XMGLog(...) NSLog(__VA_ARGS__)
167
168 #else // 发布
169
170 #define XMGLog(...)
171 作用
172 存放公用头文件和宏,自定义LOG ,编译前把PCH中的内容全部复制到每一份文件中.
173 5.设置导航条内容
174
175 思路:
176
177 - 导航条内容由栈顶控制器的navigationItem 决定,导航控制器会把栈顶控制器的View添加到自己的View上,显示在最外面的就是栈顶控制器的View.
178 精华控制器
179
180 - 设置的标题==>标题由精华控制器决定==>由精华控制器拿到navigationItem ==>self.navigationItem.titelView ;
181 - 设置导航条左侧按钮==>self.navigationItem.leftBarButtonItem
182 分析:按钮有两个状态,正常和普通.就也是要两张图片.而UIBarButtonItem 能选两张图片的只能是CustomView.
183
184 UIButton *btn = [UIButton buttonWithType:0];
185 [btn setImage:[UIImage imageNamed:@"nav_item_game_icon"] forState:0];
186 [btn setImage:[UIImage imageNamed:@"nav_item_game_click_icon"] forState:UIControlStateHighlighted];
187 [btn sizeToFit];
188 UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithCustomView:btn];
189 self.navigationItem.leftBarButtonItem = item;
190
191 //设置完成后遇到一个Bug:点击按钮以外的旁边的区域按钮也有反应==>因为:把按钮包装成UIBarButtonItem后点击范围变大
192 //解决:把按钮添加到一个UIView上,用UIView包装成UIBarButtonItem
193
194 /用UIView包装成UIBarButtonItem
195 UIView *view = [[UIView alloc]init];
196 view.bounds = btn.bounds;
197 [view addSubview:btn];
198 UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithCustomView:view];
199 self.navigationItem.leftBarButtonItem = item;
200 - 设置右侧按钮==>左右侧想似==>给UIBarButtonItem添加一个分类
201 +(UIBarButtonItem *)buttonItemWithImage:(UIImage *)image highlightImage:(UIImage *)highlightImage target:(id)target action:(SEL)action;
202 {
203 UIButton *btn = [UIButton buttonWithType:0];
204 [btn setImage:image forState:0];
205 [btn setImage:highlightImage forState:UIControlStateHighlighted];
206 [btn sizeToFit];
207
208 //监听点击
209 [btn addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];
210 //用UIView包装成UIBarButtonItem
211 UIView *view = [[UIView alloc]init];
212 view.bounds = btn.bounds;
213 [view addSubview:btn];
214 UIBarButtonItem *item = [[UIBarButtonItem alloc]initWithCustomView:view];
215 return item;
216 }
217 //注意点:监听按钮的点击时,如果要调用自己的办法,除了自身要实现方法外,还要把自己给人家传过去
218 补充
219
220 UIBarButtonItem /UINavigationItem/UITabBarItem区别
221 UIBarButtonItem:决定导航条上按钮具体内容
222 UINavigationItem:决定导航条 左边/右边/标题
223 UITabBarItem:决定UITabButton内容
224 注意点:
225 设置标题时如果self.title 设置是tabBar的title 与NavigationTitle 一连设置了.所以建议设置标题时用:navigationItem.title
226 新帖控制器
227
228 同上
229 关注控制器
230
231 同上
232 我控制器
233
234 同上
235 细节
236 设置按钮右边是两个按钮==>navigationItem.rightBarButtonItems
237 第二个按钮的图片一个是选中状态==>再给之前的分类扩充一个方法,千万不想着把之前的方法改了
238 按钮的选中状态要通过代码来设置
239 - (void)moon:(UIButton *)moon
240 {
241 moon.selected = !moon.selected;
242 NSLog(@"点击了moon");
243 }
244 设置导航条内容
245
246 设置导航条上标题字体 => 1.拿到所有导航条去设置appearance 2.谁的事情谁管理
247 分析:设置导航条标标题字体==>自定义导航控制器==>导航条标题全部都要设置==>appearance
248 导航条标题由栈顶控制器的navigationItem决定
249 self.topViewController.navigationItem.title ==>进入navigationItem没有发现可设置字体属性的==>进入父类==>UINavigationBar有titleTextAttributes
250 注意点:苹果喜欢把多个类放在同一个文件中
251 用来UINavigationBar设置title属性
252 + (void)load
253 {
254 //这种导航条背景图片都是这个
255 UINavigationBar *navigationBar = [UINavigationBar appearanceWhenContainedIn:self, nil];
256 [navigationBar setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
257
258 //设置标题属性
259 NSMutableDictionary *muDict = [NSMutableDictionary dictionary];
260 muDict[NSFontAttributeName] = [UIFont boldSystemFontOfSize:17.0];
261 muDict[NSForegroundColorAttributeName] = [UIColor blackColor];
262 navigationBar.titleTextAttributes = muDict;
263 }
264 设置界面
265
266 哪里跳转
267 在"我的"界面中点了设置按钮后跳转==>拿到导航控制器==>push压入栈
268 问题:
269 把设置界面的返回键设置成:返回,字体黑色,高亮状态:红色
270 把子控制的tabBar隐藏==>跳转之前要隐藏
271 分析:所有子控制器的返回键都是一个样==>导航条上的内容由导航控制器管理==>能不能拦截push方法.在跳转之前就做好设置.
272 - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
273 {
274 //注意点:能进去说明是非根控制器,又是在跳转之前设置好的.
275 if (self.childViewControllers.count > 0) {
276
277 //跳转之前隐藏底部tabBar==>注意:hidesBottomBarWhenPushed 是UIViewController 的一个属性,
278 //也就是任何控制器都有这个属性,只能你在显示(跳转)之前设置了就就会生效.
279 viewController.hidesBottomBarWhenPushed = YES;
280
281 //设置导航条返回键:给之前的分类增加一个方法==>需要设置到title 及什么状态的字体颜色==>传进去.
282 UIBarButtonItem *backT = [UIBarButtonItem buttonItemWithImage:[UIImage imageNamed:@"navigationButtonReturn"] highlightImage:[UIImage imageNamed:@"navigationButtonReturnClick"] title:@"返回" titleNormalColor:[UIColor blackColor] titleHighlightColor:[UIColor redColor] target:self action:@selector(back)];
283
284 viewController.navigationItem.leftBarButtonItem = backT;
285 }
286
287 //以上方法一定要在调用父类的方法之前也就是跳转之前
288 [super pushViewController:viewController animated:animated];
289
290 }