/** 图片长度截取方法 */ - (UIImage *)imageFromImage:(UIImage *)image inRect:(CGRect )rect{ CGImageRef sourceImageRef = [image CGImage]; CGImageRef newImageRef = CGImageCreateWithImageInRect(sourceImageRef, rect); UIImage *newImage = [UIImage imageWithCGImage:newImageRef]; return newImage; } SDWebImage清除缓存 #warning 注意: 清除缓存 清除缓存,一般这个清除缓存,在用户的设置里面进行操作. 如果缓存清除了.虽然减少了内存空间.但是,用户就要再请求一边,这样会费流量啊. [[SDImageCache sharedImageCache] clearDisk];//清除缓存 CollecttionView #warning 注意:布局子视图方法 //优势 // layoutAttributes可以获取到当前cell的信息 - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes { #warning 注意 层级关系...要是先添加imv 的话 我的lable 就被档下去了,文字就不见了 _lable.frame = CGRectMake(0, layoutAttributes.frame.size.height - 30, layoutAttributes.frame.size.width, 30); _lable.backgroundColor = [UIColor blackColor]; _lable.textColor = [UIColor whiteColor]; _lable.textAlignment = NSTextAlignmentCenter; _lable.alpha = 0.33; _imv.frame = CGRectMake(0, 0, layoutAttributes.frame.size.width, layoutAttributes.frame.size.height); } #warning 注意MRC情况下 set的写法 - (void)setModel:(Model *)model { if (_model != model) { [_model release]; _model = [model retain]; //赋值 self.lable.text = [NSString stringWithFormat:@"%@",model.height]; [self.imv sd_setImageWithURL:[NSURL URLWithString:model.thumbURL] placeholderImage:[UIImage imageNamed:@"placeHoderImage"]]; } } 字符串 #warning 这个比较新鲜, 中文转码(如果网址中有中文,需要中文转码) //赛选中文 / 中文转码 NSString *newStr = [str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:str]]; + (void)musicModelRequest:(MusicModel *)model{ NSString *str = model.lyric; #warning 拆分字符串,放到数组中 NSArray *array = [str componentsSeparatedByString:@" "]; //见到/n就把这个字符串放到数组中 //区分时间与歌词 NSMutableArray *timeMutableArray = [NSMutableArray array]; //接收时间 NSMutableArray *lyricMutableArray = [NSMutableArray array]; //接收歌词 for (NSString *string in array) { NSArray *timeAndLyric = [string componentsSeparatedByString:@"]"];//拆分时间与歌词 [lyricMutableArray addObject:timeAndLyric.lastObject]; NSArray *timeArray = [timeAndLyric.firstObject componentsSeparatedByString:@"["];//拆分时间 [timeMutableArray addObject:timeArray.lastObject]; } //赋值 model.timeArray = [NSArray arrayWithArray:timeMutableArray]; model.lyricArray = [NSArray arrayWithArray:lyricMutableArray]; } XIB StorryBorad可视化 #warning 注意: View创建方法... - (void)loadView { //参数1要加载的XIB文件 参数2文件拥有者 参数3加载选项 self.htView = [[NSBundle mainBundle] loadNibNamed:@"HTView" owner:self options:nil].firstObject; self.view = _htView; } #warning 注意: View改文字改属性,在这儿 #import "TextView.h" @implementation TextView //改文字,改属性在这儿 - (void)awakeFromNib { self.titleLable.text = @"改文字,改属性在这儿"; } @end #warning 注意:Cell注册..... //注册 // [self.tableView registerClass:[SecondViewController class] forCellReuseIdentifier:cell_id_Second]; [self.tableView registerNib:[UINib nibWithNibName:@"SecondTableViewCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:cell_id_Second]; #warning 注意:使用storyBoard关联的类不再使用init方法创建,直接去storyBorad里面找有当前标识符的视图控制器的拖放面板. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { UIStoryboard *st = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];//1、先去当前包里找到故事版 TextViewController *textVC = [st instantiateViewControllerWithIdentifier:@"testViewController"];//2、根据标示符,在故事版中找到当前视图控制器 [self.navigationController pushViewController:textVC animated:YES]; } #warning 获取路径 - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { NSIndexPath *path = [self.tableView indexPathForCell:sender]; //获取路径。。。。。 关键呀.****************************************************** DetailViewController *detal = segue.destinationViewController; detal.string = _array[path.row]; } TabBar #warning 图片这块注意:@2x作用,系统自动匹配大小. #warning PUS后 隐藏TabBar - (void)buttonAction:(UIButton *)sender { TextViewController *text = [[[TextViewController alloc] init] autorelease]; text.hidesBottomBarWhenPushed = YES;PUS页面的时候隐藏tabBar [self.navigationController pushViewController:text animated:YES]; //有些应用点击的时候隐藏 导航栏 和 标签栏. 是这样做的 // self.navigationController.navigationBar.hidden = YES; // self.tabBarController.tabBar.hidden = YES; //在手势点击事件里设置。根据点击此时,奇偶数进行判断就OK了 } #pragma mark 当点击标签栏的时候触发此方法 - (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { if (viewController.tabBarItem.badgeValue != nil) { viewController.tabBarItem.badgeValue = nil; } NSLog(@"%ld",tabBarController.selectedIndex);//输出选中下标,做下演示 } BLOCK //MRC销毁 - (void)dealloc { #warning block 的释放只能使用Block_release() //系统写好的释放方法 Block_release(_myBlock); //因为block不是一个对象类型不能使用relese,是函数. Block_release(_cBlock);//释放 [_textField release]; [super dealloc]; NSLog(@"验证dealloc成功"); } - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { #warning //block就是一个回调函数,相当于小弟,什么时候用,什么时候调。 哈哈 //block(函数) 调用 _myBlock(_textField.text); #warning 解决循环引用问题 //记住:Block 实现部分不能直接使用属性、实力变量 和 self 去调用; 因为会照成循环引用就是相互持有(不会走dealloc方法), 例如:[self text];这样调用, 错得。循环引用了. //////////解决循环引用问题演示: //MRC: //第一种写法 __block SecondViewController *temp = self; //第二种写法: //__block typeof(self) temp = self; //ARC: //__weak SecondViewController *temp = self; //实现 self.cBlock = ^(){ [temp text]; }; //调用 temp.cBlock(); [self.navigationController popViewControllerAnimated:YES]; } #import <UIKit/UIKit.h> typedef void(^MyBlock) (NSString *); //定义有参,无返回值的匿名函数传递字符串; 这是函数 typedef void (^Block)(); //做内存测试 @interface SecondViewController : UIViewController @property(nonatomic,retain)UITextField *textField; //MRC: block的语义设置是copy 把block从栈区 拷贝到 堆区 。使用完之后,在dealoc 里面释放.(blcok是函数,函数在栈区) //ARC:block的语义设置使用strong 即可 @property(nonatomic,copy)MyBlock myBlock; //参数 函数 @property(nonatomic,copy)Block cBlock; @end 单例 #warning 单例 //创建静态区对象的原因:希望程序运行期间它在程序中一直存在,这样对外界来说,可以随时读取数据. //我们创建单例使用加号方法的原因是因为:在创建之前,无法存在一个实例对象去调用动态方法来创建它本身 /////劣势:创建多了,会影响性能,内存空间减小。程序会卡.因为是在停留静态区。生命周期,与程序同步。 /////优势:降低耦合性,降低复杂性; 可以全局访问 ;在内存中只有一个对象,节省内存空间;避免频繁的创建销毁对象,提高性能;避免对共享资源的多重占用. //完整单例手写吧 //+ (instancetype)sharedDaraHandle //{ // static DataHandle *dataHandle = nil; // static dispatch_once_t onceToken; // dispatch_once(&onceToken, ^{ // // dataHandle = [[DataHandle alloc] init]; // // }); // // return dataHandle; //} 文本高度自适应 + 图片高度自适应 + Cell注意事项 //heightForRowAtIndexPath 这个方法会比cellForRowAtIndexPath先执行,所以我们需要先计算好cell高度, #warning 注意:注意:注意:只有cell要在layoutSubViews里面布局,因为这个方法最后走,cell需要重用.所以在这里布局. #warning 注意:最后走这个方法, 还有 图片自适应及文本自适应! 以及layoutSubviews方法里self的宽 和 高 与 初始化里面的不同. //最后走这个方法 - (void)layoutSubviews { [super layoutSubviews]; #warning 注意:注意:注意:这里千万不能这样赋值 _lable.frame = self.frame 要这样_lable.frame = self.contentView.frame #warning 注意:注意:注意:这里千万不能这样赋值 _lable.frame = self.frame 要这样_lable.frame = self.contentView.frame #warning 注意:注意:注意:这里千万不能这样赋值 _lable.frame = self.frame 要这样_lable.frame = self.contentView.frame //图片高度自适应 CGFloat height = self.imv.image.size.height * self.contentView.frame.size.width / self.imv.image.size.width; self.imv.frame = CGRectMake(0, 0, self.contentView.frame.size.width, height); self.imv.backgroundColor = [UIColor grayColor]; //lable高度自适应 CGFloat lableHeight = [self myHeight:self.lable.text]; self.lable.frame = CGRectMake(0, height, self.contentView.frame.size.width, lableHeight); self.lable.backgroundColor = [UIColor orangeColor]; self.lable.numberOfLines = 0; self.lable.font = [UIFont systemFontOfSize:17]; NSLog(@"--------W:%lf H:%lf",self.frame.size.width,self.frame.size.height); } - (CGFloat)myHeight:(NSString *)string { CGRect rect = [string boundingRectWithSize:CGSizeMake(self.frame.size.width, 100000) options:NSStringDrawingUsesLineFragmentOrigin attributes:@{NSFontAttributeName : [UIFont systemFontOfSize:17]} context:nil]; return rect.size.height; } #warning UILable和UIImageView 的用户交互,默认是关闭的 懒加载 #pragma mark 懒加载 重写get方法 //原来这也是懒加载,实质就是get方法(懒加载——也称为延迟加载,即在需要的时候才加载(效率低,占用内存小)。) - (void)addAllViews{ [self addSubview:self.nameLabel]; //懒加载(用了点语法,才能调用get方法) [self addSubview:self.nameTextField]; //懒加载 } #pragma mark 懒加载 重写get方法 - (UILabel *)nameLabel{ if (!_nameLabel) { #warning 注意,创建的时候一定要用self. 点语法创建, 不要_nameLable这样取创建 self.nameLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 30)]; _nameLabel.text = @"懒加载"; } return _nameLabel; } #pragma mark 布局子视图 //布局子视图(从新布局view. 此方法,自动触发,程序最后走这个方法) - (void)layoutSubviews{ //[UIApplication sharedApplication].statusBarOrientation //statusBarOrientation状态栏方向(应用程序) if ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeLeft || [UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationLandscapeRight) { [super layoutSubviews]; _nameTextField.frame = CGRectMake(150, 20, 400, 50); _nameTextField.backgroundColor = [UIColor redColor]; //如果是横屏,XXXX }else{ [super layoutSubviews]; //如果是竖屏,XXXX _nameTextField.frame = CGRectMake(0, 120, 150, 30); _nameTextField.backgroundColor = [UIColor whiteColor]; } //(这里是根据应用程序的状态栏方向,来从新布局子时视图) } //此方法,绘图的时候,用 - (void)drawRect:(CGRect)rect { // Drawing code 绘图时候用 } 从写Model的Get方法 赋值时, 注意: 在if {} 花括号外边进行.