框架搭建的注意点
怎样设置cell的左右有间距 ->自定义cell中修改cell的frame
- (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) {
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.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];
viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
viewController.hidesBottomBarWhenPushed = YES;
}
[super pushViewController:viewController animated:animated];
}
在自定义的UITabBarController中,通过appearance统一设置所有UITabBarItem的属性
+ (void)initialize
{
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];
[self setValue:[[AHTabBar alloc] init] forKeyPath:@"tabBar"];
}
在自定义的UINavigationController中,通过appearance统一设置UINavigationBar
/** * 当第一次使用这个类的时候会调用一次UINavigationBar的属性 */
+ (void)initialize
{
UINavigationBar *bar = [UINavigationBar appearance];
[bar setBackgroundImage:[UIImage imageNamed:@"navigationbarBackgroundWhite"] forBarMetrics:UIBarMetricsDefault];
}
如何修改导航栏的内容
- 修改导航栏上的
leftBarButtoniItem
和 rightBarButtoniItem
可以写一个分类
#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 *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;
Ivar *ivars = class_copyIvarList([UITextField class], &count);
for (int i = 0; i<count; 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;
[button setTitle:@"已有账号?" forState:UIControlStateNormal];
} else {
self.loginViewLeftMargin.constant = 0;
[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];
fmt.dateFormat = @"yyyy-MM-dd HH:mm:ss";
NSDate *create = [fmt dateFromString:create_time];
NSTimeInterval delta = [now timeIntervalSinceDate:create];
NSDate *now = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
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);
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
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);
#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
{
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
{
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小时前
- 昨天
- 其他
- 非今年
- 2015-05-08 18:45:30
在AHTopic模型中,重写create_time get方法
- (NSString *)create_time{
NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
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) {
return [NSString stringWithFormat:@"%zd小时前", cmps.hour];
} else if (cmps.minute >= 1) {
return [NSString stringWithFormat:@"%zd分钟前", cmps.minute];
} else {
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;
}
}