框架搭建的注意点

怎样设置cell的左右有间距 ->自定义cell中修改cell的frame

  • 重写cell的setFrameL:方法
- (void)setFrame:(CGRect)frame{frame.origin.x += 5;frame.size.width -= 10;frame.size.height -= 1;[super setFrame:frame];
}

自定义NavigationController,拦截所有push进来的控制器

  • 自定义NavigationController,重写pushViewController:animated:方法
- (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
{if (self.childViewControllers.count > 0) { // 如果push进来的不是第一个控制器UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];[button setTitle:@"返回" forState:UIControlStateNormal];[button setImage:[UIImage imageNamed:@"navigationButtonReturn"] forState:UIControlStateNormal];[button setImage:[UIImage imageNamed:@"navigationButtonReturnClick"] forState:UIControlStateHighlighted];button.size = CGSizeMake(70, 30);// 让按钮内部的所有内容左对齐button.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft;
//        [button sizeToFit];// 让按钮的内容往左边偏移10button.contentEdgeInsets = UIEdgeInsetsMake(0, -10, 0, 0);[button setTitleColor:[UIColor blackColor] forState:UIControlStateNormal];[button setTitleColor:[UIColor redColor] forState:UIControlStateHighlighted];[button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];// 修改导航栏左边的itemviewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];// 隐藏tabbarviewController.hidesBottomBarWhenPushed = YES;}// 这句super的push要放在后面, 让viewController可以覆盖上面设置的leftBarButtonItem[super pushViewController:viewController animated:animated];}

在自定义的UITabBarController中,通过appearance统一设置所有UITabBarItem的属性

+ (void)initialize
{// 通过appearance统一设置所有UITabBarItem的文字属性// 后面带有UI_APPEARANCE_SELECTOR的方法, 都可以通过appearance对象来统一设置NSMutableDictionary *attrs = [NSMutableDictionary dictionary];attrs[NSFontAttributeName] = [UIFont systemFontOfSize:12];attrs[NSForegroundColorAttributeName] = [UIColor grayColor];NSMutableDictionary *selectedAttrs = [NSMutableDictionary dictionary];selectedAttrs[NSFontAttributeName] = attrs[NSFontAttributeName];selectedAttrs[NSForegroundColorAttributeName] = [UIColor darkGrayColor];UITabBarItem *item = [UITabBarItem appearance];[item setTitleTextAttributes:attrs forState:UIControlStateNormal];[item setTitleTextAttributes:selectedAttrs forState:UIControlStateSelected];
}

设置UITabBarItem的图片时,UITabBarItem选中时的图标(selectedImage)对应的图片会被xcode自动渲染成蓝色样式,如何取消图片的自动渲染效果?



vc.tabBarItem.title = title;
vc.tabBarItem.image = [UIImage imageNamed:image];
vc.tabBarItem.selectedImage = [UIImage imageNamed:selectedImage];

如何自定义UITabBarController的UITabBar

  • 自定义一个UITabBar
  • 在TabBarController中更换tabBar
- (void)viewDidLoad
{[super viewDidLoad];// 更换tabBar[self setValue:[[AHTabBar alloc] init] forKeyPath:@"tabBar"];
}

在自定义的UINavigationController中,通过appearance统一设置UINavigationBar

/*** 当第一次使用这个类的时候会调用一次UINavigationBar的属性*/
+ (void)initialize
{// 当导航栏用在AHNavigationController中, appearance设置才会生效// UINavigationBar *bar = [UINavigationBar appearanceWhenContainedIn:[self class], nil];UINavigationBar *bar = [UINavigationBar appearance];[bar setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
}

如何修改导航栏的内容

  • 修改导航栏上的leftBarButtoniItemrightBarButtoniItem可以写一个分类
#import <UIKit/UIKit.h>@interface UIBarButtonItem (AHExtension)
+ (instancetype)itemWithImage:(NSString *)image highImage:(NSString *)highImage target:(id)target action:(SEL)action;
@end
#import "UIBarButtonItem+AHExtension.h"@implementation UIBarButtonItem (AHExtension)
+ (instancetype)itemWithImage:(NSString *)image highImage:(NSString *)highImage
target:(id)target action:(SEL)action
{UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];[button setBackgroundImage:[UIImage imageNamed:image] forState:UIControlStateNormal];[button setBackgroundImage:[UIImage imageNamed:highImage] forState:UIControlStateHighlighted];button.size = button.currentBackgroundImage.size;[button addTarget:target action:action forControlEvents:UIControlEventTouchUpInside];return [[self alloc] initWithCustomView:button];
}
@end
- (void)viewDidLoad
{[super viewDidLoad];// 设置导航栏标题self.navigationItem.title = @"我的关注";// 设置导航栏左边的按钮self.navigationItem.leftBarButtonItem = [UIBarButtonItem itemWithImage:@"friendsRecommentIcon" highImage:@"friendsRecommentIcon-click" target:self action:@selector(friendsClick)];// 设置背景色self.view.backgroundColor = [UIColor blockColor];
}

登录注册界面的注意点

状态栏颜色的更改

/*** 让当前控制器对应的状态栏是白色*/
- (UIStatusBarStyle)preferredStatusBarStyle{return UIStatusBarStyleLightContent;
}

修改文本框占位文字的颜色

  • 设置文本框的attributedPlaceholder 属性

    • @property(nullable, nonatomic,copy) NSAttributedString *attributedPlaceholder
    • NSAttributedString 带有属性的文字
    // 文字属性NSMutableDictionary *attrs = [NSMutableDictionary dictionary];attrs[NSForegroundColorAttributeName] = [UIColor grayColor];// NSAttributedString : 带有属性的文字(富文本技术)NSAttributedString *placeholder = [[NSAttributedString alloc] initWithString:@"手机号" attributes:attrs];self.phoneField.attributedPlaceholder = placeholder;
    NSMutableAttributedString *placehoder = [[NSMutableAttributedString alloc] initWithString:@"手机号"];[placehoder setAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor]} range:NSMakeRange(0, 1)];[placehoder setAttributes:@{NSForegroundColorAttributeName : [UIColor yellowColor],NSFontAttributeName : [UIFont systemFontOfSize:30]} range:NSMakeRange(1, 1)];[placehoder setAttributes:@{NSForegroundColorAttributeName : [UIColor redColor]} range:NSMakeRange(2, 1)];self.phoneField.attributedPlaceholder = placehoder;
  • 自定义TextField,重写drawPlaceholderInRect: 方法
- (void)drawPlaceholderInRect:(CGRect)rect
{[self.placeholder drawInRect:CGRectMake(0, 10, rect.size.width, 25) withAttributes:@{NSForegroundColorAttributeName : [UIColor grayColor],NSFontAttributeName : self.font}];
}
  • 使用KVC

    • 运行时(Runtime)找到_placeholderLabel.textColor,使用KVC更改颜色
      [self setValue:[UIColor grayColor] forKeyPath:@"_placeholderLabel.textColor"];
    • 完整代码实现,自定义一个TextField,实现一下方法
- (void)awakeFromNib{// 设置光标颜色和文字颜色一致self.tintColor = self.textColor;// 不成为第一响应者[self resignFirstResponder];
}/*** 当前文本框聚焦时就会调用*/
- (BOOL)becomeFirstResponder{// 修改占位文字颜色[self setValue:self.textColor forKeyPath:@"_placeholderLabel.textColor"];return [super becomeFirstResponder];
}/*** 当前文本框失去焦点时就会调用*/
- (BOOL)resignFirstResponder{// 修改占位文字颜色[self setValue:[UIColor grayColor] forKeyPath:@"_placeholderLabel.textColor"];return [super resignFirstResponder];
}

运行时(Runtime)

  • 苹果官方一套C语言库
  • 能做很多底层操作(比如访问隐藏的一些成员变量\成员方法….)
  • 访问成员变量举例
unsigned int count = 0;// 拷贝出所有的成员变量列表
//(类似于这样的就是属性@property(nonatomic, strong) UIView *view)
Ivar *ivars = class_copyIvarList([UITextField class], &count);for (int i = 0; i<count; i++) {// 取出成员变量// Ivar ivar = *(ivars + i);Ivar ivar = ivars[i];// 打印成员变量名字XMGLog(@"%s", ivar_getName(ivar));
}// 释放
free(ivars);
// 拷贝出所有的属性列表
unsigned int count = 0;objc_property_t *properties = class_copyPropertyList([UITextField class], &count);for (int i = 0; i<count; i++) {// 取出属性objc_property_t property = properties[i];// 打印属性名字, 属性类型XMGLog(@"%s   <---->   %s", property_getName(property), property_getAttributes(property));
}free(properties);

注册框,登陆框的切换

  • 注册框的约束

    • 左边约束设置为紧挨着登陆框的右边
    • 顶部约束设置为和登陆框的顶部同高
    • 宽度约束设置为和登录框的约束同高.
  • 让控制器拥有登录框左边的约束属性
  • 点击按钮时,根据情况更改登录框的左边的约束 的 constant
    // 退出键盘[self.view endEditing:YES];if (self.loginViewLeftMargin.constant == 0) { // 显示注册界面self.loginViewLeftMargin.constant = - self.view.width;// 还可以在xib中设置 selected 样式下的文字为已有账号? // 通过设置按钮selected的值,控制按钮的文字// button.selected = YES;[button setTitle:@"已有账号?" forState:UIControlStateNormal];} else { // 显示登录界面self.loginViewLeftMargin.constant = 0;// button.selected = NO;[button setTitle:@"注册账号" forState:UIControlStateNormal];}[UIView animateWithDuration:0.25 animations:^{[self.view layoutIfNeeded];}];

推送引导

  • 取出当前的版本号,再获得沙盒中存储的版本号
  • 当前的版本号不等于沙盒中存储的版本号,自定义一个View作为推送引导界面,添加到window上面
  • 存储当前的版本号
NSString *key = @"CFBundleShortVersionString";// 获得当前软件的版本号
NSString *currentVersion = [NSBundle mainBundle].infoDictionary[key];
// 获得沙盒中存储的版本号
NSString *sanboxVersion = [[NSUserDefaults standardUserDefaults] stringForKey:key];if (![currentVersion isEqualToString:sanboxVersion]) {UIWindow *window = [UIApplication sharedApplication].keyWindow;XMGPushGuideView *guideView = [XMGPushGuideView guideView];guideView.frame = window.bounds;[window addSubview:guideView];// 存储版本号[[NSUserDefaults standardUserDefaults] setObject:currentVersion forKey:key];[[NSUserDefaults standardUserDefaults] synchronize];
}

精华模块

计算两个日期(NSDate)的时间差值

  • 基本方法
// 当前时间
NSDate *now = [NSDate date];// 创建日期格式化类
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
// 设置日期格式(y:年,M:月,d:日,H:时,m:分,s:秒)
fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";
// 发帖时间
NSDate *create = [fmt dateFromString:create_time];// 当前时间和发帖时间的差值(按秒计算)
NSTimeInterval delta = [now timeIntervalSinceDate:create];
  • NSCalendar

    • 获得NSDate的每一个元素
    • 比较时间
// 获得NSDate的每一个元素
NSDate *now = [NSDate date];
// 日历
NSCalendar *calendar = [NSCalendar currentCalendar];// 获得NSDate的每一个元素
NSInteger year = [calendar component:NSCalendarUnitYear fromDate:now];
NSInteger month = [calendar component:NSCalendarUnitMonth fromDate:now];
NSInteger day = [calendar component:NSCalendarUnitDay fromDate:now];
NSDateComponents *cmps = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:now];
NSLog(@"%zd %zd %zd", cmps.year, cmps.month, cmps.day);
// 计算两个日期(NSDate)的时间差值// 日期格式化类
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
// 设置日期格式(y:年,M:月,d:日,H:时,m:分,s:秒)
fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";// 当前时间
NSDate *now = [NSDate date];
// 发帖时间
NSDate *create = [fmt dateFromString:create_time];// 日历
NSCalendar *calendar = [NSCalendar currentCalendar];// 比较时间
NSCalendarUnit unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *cmps = [calendar components:unit fromDate:create toDate:now options:0];
NSLog(@"%@ %@", create, now);
NSLog(@"%zd %zd %zd %zd %zd %zd", cmps.year, cmps.month, cmps.day, cmps.hour, cmps.minute, cmps.second);
  • 写一个SNDate的分类
#import <Foundation/Foundation.h>@interface NSDate (AHExtension)
/*** 比较from和self的时间差值*/
- (NSDateComponents *)deltaFrom:(NSDate *)from;/*** 是否为今年*/
- (BOOL)isThisYear;/*** 是否为今天*/
- (BOOL)isToday;/*** 是否为昨天*/
- (BOOL)isYesterday;
@end
#import "NSDate+AHExtension.h"@implementation NSDate (AHExtension)- (NSDateComponents *)deltaFrom:(NSDate *)from{// 日历NSCalendar *calendar = [NSCalendar currentCalendar];// 比较时间NSCalendarUnit unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;return [calendar components:unit fromDate:from];
}- (BOOL)isThisYear
{// 日历NSCalendar *calendar = [NSCalendar currentCalendar];NSInteger nowYear = [calendar component:NSCalendarUnitYear fromDate:[NSDate date]];NSInteger selfYear = [calendar component:NSCalendarUnitYear fromDate:self];return nowYear == selfYear;
}//- (BOOL)isToday
//{//    // 日历
//    NSCalendar *calendar = [NSCalendar currentCalendar];
//
//    NSCalendarUnit unit = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay;
//
//    NSDateComponents *nowCmps = [calendar components:unit fromDate:[NSDate date]];
//    NSDateComponents *selfCmps = [calendar components:unit fromDate:self];
//
//    return nowCmps.year == selfCmps.year
//    && nowCmps.month == selfCmps.month
//    && nowCmps.day == selfCmps.day;
//}- (BOOL)isToday
{NSDateFormatter *fmt = [[NSDateFormatter alloc] init];fmt.dateFormat = @"yyyy-MM-dd";NSString *nowString = [fmt stringFromDate:[NSDate date]];NSString *selfString = [fmt stringFromDate:self];return [nowString isEqualToString:selfString];
}- (BOOL)isYesterday
{// 2014-12-31 23:59:59 -> 2014-12-31// 2015-01-01 00:00:01 -> 2015-01-01// 日期格式化类NSDateFormatter *fmt = [[NSDateFormatter alloc] init];fmt.dateFormat = @"yyyy-MM-dd";NSDate *nowDate = [fmt dateFromString:[fmt stringFromDate:[NSDate date]]];NSDate *selfDate = [fmt dateFromString:[fmt stringFromDate:self]];NSCalendar *calendar = [NSCalendar currentCalendar];NSDateComponents *cmps = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear fromDate:selfDate toDate:nowDate options:0];return cmps.year == 0&& cmps.month == 0&& cmps.day == 1;
}

时间的格式化

  • 今年

    • 今天

      • 一分钟内:刚刚
      • 一小时内:XX分钟前
      • 其他:XX小时前
    • 昨天
      • 昨天 19:20:30
    • 其他
      • 02-28 19:20:30
  • 非今年
    • 2015-05-08 18:45:30
      在AHTopic模型中,重写create_time get方法
- (NSString *)create_time{// 日期格式化类NSDateFormatter *fmt = [[NSDateFormatter alloc] init];// 设置日期格式(y:年,M:月,d:日,H:时,m:分,s:秒)fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";// 帖子的创建时间NSDate *create = [fmt dateFromString:_create_time];if (create.isThisYear) { // 今年if (create.isToday) { // 今天NSDateComponents *cmps = [[NSDate date] deltaFrom:create];if (cmps.hour >= 1) { // 时间差距 >= 1小时return [NSString stringWithFormat:@"%zd小时前", cmps.hour];} else if (cmps.minute >= 1) { // 1小时 > 时间差距 >= 1分钟return [NSString stringWithFormat:@"%zd分钟前", cmps.minute];} else { // 1分钟 > 时间差距return @"刚刚";}} else if (create.isYesterday) { // 昨天fmt.dateFormat = @"昨天 HH:mm:ss";return [fmt stringFromDate:create];} else { // 其他fmt.dateFormat = @"MM-dd HH:mm:ss";return [fmt stringFromDate:create];}} else { // 非今年return _create_time;}
}

百思不得其姐的注意点相关推荐

  1. [经验]无线鼠标和无线键盘真的不能用了?——雷柏的重生之路~

    逆天大二的时候托朋友买了个雷柏的无线键盘鼠标: 用了很多年,不仅外观好而且键盘鼠标本身也很好用,可前些日子就光荣牺牲了.... 逆天百思不得其"姐",试着把电池换了,发现还是不行, ...

  2. python什么时候要缩进_不归路系列:Python入门之旅-一定要注意缩进!!!(推荐)...

    因为工作(懒惰),几年了,断断续续学习又半途而废了一个又一个技能.试着开始用博客记录学习过程中的问题和解决方式,以便激励自己和顺便万一帮助了别人呢. 最近面向对象写了个Python类,到访问限制(私有 ...

  3. Authentication Error errorcode: 230 uid: -1 appid -1 msg: APP Scode码校验失败

    开发和发布的都一样,包名也没错.百思不得其姐. 找到这篇文章 http://blog.csdn.net/hhhccckkk/article/details/46649325 感谢分享的亲们,省了好多时 ...

  4. 十年硬件老司机,结合实际案例,带你探索单片机低功耗设计!

    作者:YJGQDD(阿莫:hailing),整理:晓宇 微信公众号:芯片之家(ID:chiphome-dy) 经过了多年的低功耗硬件设计(公司硬件设计和软件设计是分开的,我一直是做硬件,在面对低功耗生 ...

  5. 编译安装 zbar 时两次 make 带来的惊喜

    为了装 php 的条形码扩展模块 php-zbarcode,先装了一天的 ImageMagick 和 zbar.也许和我装的 Ubuntu 17.10 的有版本兼容问题吧,总之什么毛病都有,apt 不 ...

  6. 菜鸟读jQuery 2.0.3 源码分析系列(1)

    原文链接在这里,作为一个菜鸟,我就一边读一边写 jQuery 2.0.3 源码分析系列 前面看着差不多了,看到下面一条(我是真菜鸟),推荐木有入门或者刚刚JS入门摸不着边的看看,大大们手下留情,想一起 ...

  7. 几个容器网络相关问题的分析和解决总结(续1)

    [摘要] 上次我发了"几个容器网络相关问题的分析和解决总结"后,有的童鞋已经能照猫画虎地解决容器网络问题了,我心甚慰.前几天我又不务正业地帮忙分析解决了几个影响版本发布的网络问题. ...

  8. react: code-split

    百思不得其姐- 然后今天不忙就早点回家搞搞 看看收获:(发现不能上传视频有点伤)

  9. rails将类常量重构到数据库对应的表中之二

    在博文之一中我们将Order中的常量重构到了数据库的表中,也做了一些测试,貌似一切都很完美.可是...梦魔还未开始啊!我们少做了一步测试,就是rake test! 结果惨不忍睹,所有测试都是E,全部出 ...

  10. Hive怎样加入第三方JAR

    以增加elsaticsearch-hadoop-2.1.2.jar为例,讲述在Hive中增加第三方jar的几种方式. 1,在hive shell中增加 [hadoop@hadoopcluster78 ...

最新文章

  1. 我研究了最热门的200种AI工具,却发现这个行业有点饱和
  2. VHDL硬件描述语言(二)——子程序
  3. SAP-FICO-AR-关于剩余支付和部分支付的区别
  4. Python Pandas –数据输入和输出
  5. java写html的多选框,Selenium+java - 单选框及复选框处理
  6. 二范数-特征值的意义-矩阵范数-向量范数-
  7. 阵列信号处理知识点合集
  8. Unity制作简单动画效果
  9. 【对讲机的那点事】玩无线电,你知道无线电信号是怎样发送和接收的?
  10. ubuntu死机咋办_Ubuntu死机解决方法汇总
  11. GCC编译器下C语言不定长参数宏##__VA_ARGS__和__VA_ARGS__的使用
  12. 人工智能下的中秋祝福
  13. 灿烂星空,你是真的英雄
  14. 认识Innodb存储引擎
  15. 『递推』[AGC043D] Merge Triplets
  16. 【内网穿透】通过WebDAV服务访问群晖NAS文件
  17. 小学科学杂志小学科学杂志社小学科学编辑部2022年第12期目录
  18. 基于51单片机的多路多点温度检测两种供电方式proteus仿真原理图PCB
  19. C调用shellcode方法总结
  20. 12个有效的域名工具及其生成器

热门文章

  1. mysql语句大全文档_mysql语句大全免费
  2. 分享个PS快速替换背景颜色的方法
  3. Python 随机漫步
  4. [容斥 状压DP] Atcoder ARC093 F - Dark Horse
  5. arc093F Dark Horse
  6. 使用OpenCV,Python和dlib进行眨眼检测
  7. Windows Print Spooler远程代码执行漏洞复现(CVE-2021-1675)
  8. oracle创建数据库的先决条件,Oracle数据库安装先决条件检查失败解决方案
  9. jt808终端鉴权_JT/T808协议文档-道路运输车辆卫星定位系统北斗兼容车载终端通讯协议技术规范.pdf...
  10. 达梦数据库解决ZYJ环境数据库连接会闪断的问题