1.iOS11上上出现UIToolbar上添加按钮,button点击事件无法响应问题
解决办法: 在iOS11以上的情况下 UIToolbar的UIToolbarContentView会出现覆盖在视图最上层情况,导致后续添加的按钮无法点击,所以为了避免这种情况下按钮无法点击
需要在将UIToolbar添加到UI层上之后立马[toolbar layoutIfNeeded];。降低UIToolbarContentView的层级关系
2.在iPhone5C上 [UIFont fontWithName:familyNamed size:font] 方法不会被正确执行
解决办法:需要修改为系统的[UIFont systemFontOfSize:font];
3.系统自带UIAlertController弹出延迟问题
解决办法:可使用回到主线程进行弹出,有效避免系统弹框延迟问题
dispatch_async(dispatch_get_main_queue(), ^{
[self presentViewController:alert animated:true completion:nil];
});
4.WKWebView上使用自定义UIMenuController
小伙伴们可以测试一下,WKWebView正常情况下是无法取消掉系统自带的复制,粘贴,全选等选项的
如果当前WKWebView中没有弹出键盘需求的话可直接使用以下办法弹出自定义按钮
- (BOOL)canResignFirstResponder{
if (_dismissSelf) {
return YES;
}
return NO;
}
- (void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
self.dismissSelf = YES;
}
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
self.dismissSelf = NO;
}
@warning _dismissSelf 这个布尔值的意义在为NO时,可展示自定义的UIMenuItem,
但是- (BOOL)canResignFirstResponder这个函数返回是全局都做修改的。
如果退出当前界面还是为NO的话,那么我们项目中所有的键盘弹出将不起作用
5.UISearchBar相关问题
-(UISearchBar *)poiSearchBar{
if (!_poiSearchBar) {
_poiSearchBar = [[UISearchBar alloc]init];
_poiSearchBar.backgroundImage = [[UIImage alloc]init];
_poiSearchBar.barTintColor = [UIColor uiColorFromString:@"#f0f3f8"];
_poiSearchBar.placeholder = @"请输入检索信息";
_poiSearchBar.delegate = self;
_poiSearchBar.barStyle = UIBarStyleDefault;
_poiSearchBar.tintColor = [UIColor redColor];
[_poiSearchBar setImage:[UIImage imageNamed:@"search_Icon"] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal];
// 设置圆角和边框颜色
UITextField * searchF = [_poiSearchBar valueForKey:@"searchField"];// KVO获取私有变量
if (searchF) {
[searchF setBackgroundColor:[UIColor uiColorFromString:@"#f0f3f8"]];
[searchF setValue:[UIFont boldSystemFontOfSize:13] forKeyPath:@"_placeholderLabel.font"];//KVC
searchF.returnKeyType = UIReturnKeySearch;
searchF.layer.cornerRadius = 5;
searchF.layer.borderWidth = 1;
searchF.layer.borderColor = [UIColor redColor].CGColor;
searchF.layer.masksToBounds = YES;
[searchF setTintColor:[UIColor uiColorFromString:@"#1997eb"]];
}
}
return _poiSearchBar;
}
搜索框上取消按钮
-(void)searBarText:(UISearchBar*)searchBar{
searchBar.showsCancelButton = YES;
for (UIView * view in [[[searchBar subviews] objectAtIndex:0] subviews]) {
if ([view isKindOfClass:[NSClassFromString(@"UINavigationButton")class]]) {
UIButton * cancle = (UIButton *)view;
cancle.hidden = NO;
[cancle setTitle:@"取消" forState:UIControlStateNormal];
[cancle setTitleColor:[UIColor uiColorFromString:@"#f0f3f8"] forState:UIControlStateNormal];
cancle.enabled = YES;//系统默认为NO.为了达到没有输入文字直接点击取消可以返回之前的界面。而不是第一次点击取消会获取焦点走searchBarTextDidBeginEditing方法 。需要在找到取消按钮的时候设置为YES
cancle.titleLabel.font = [UIFont systemFontOfSize:15];
[cancle addTarget:self action:@selector(cancleButton:) forControlEvents:UIControlEventTouchUpInside];
}
}
}
UISearchBar解析
(1)改变背景色
找到_searchbar.subviews 数组中的第一个view。自定义一个view添加背景色放在上变
(2)不显示背景色
样式中(searchBarStyle)选择 UISearchBarStyleMinimal //不显示背景色
(3)改变输入框的圆角
找到textfield UITextfield * textF = [_searchBar valueForKey:”searchField”]navBo如果存在改变圆角。
(4)改变提示字体的大小
利用KVC 实现改变提示字体的大小
[_textfield setValue:[UIFont boldSystemFontOfSize:字体大小]
6.消除头部停留
-(void)scrollViewDidScroll:(UIScrollView*)scrollerView{
CGFloat section = 区头高度
if(scrollView.contentOffset.y < section && scrollView.contentOffset.y >0){
scrollView.contentInset = UIEdgeInsetsMake(-scrollView.contentOffset.y,0,0,0)
}else if {
scrollView.contentInset = UIEdgeInsetMake(-section,0,0,0)
}
}
7.多个字符串拼接(举例以逗号拼接)
NSArray *strs = [@"a", @"b", @"c"];
NSString *string = [strs componentsJoinedByString:@","];
8.多个字符串(单个)分隔 (举例以逗号分隔)
NSString *a = [[NSString alloc] initWithString : @"冬瓜,西瓜,火龙果,大头,小狗" ];
NSArray *b = [a componentsSeparatedByString:@","];
9.截取字符串
- (NSString *)substringFromIndex:(NSUInteger)from; 从哪个位置其到尾
- (NSString *)substringToIndex:(NSUInteger)to; 从开头到哪个位置
- (NSString *)substringWithRange:(NSRange)range; 从哪到哪之间的位置
10.分隔指定字符串
NSArray *resultArr1 = [stringcomponentsSeparatedByString:@"_"];
11.替换某一个字符串
NSString * string=@"2011-11-29";
string=[string stringByReplacingOccurrencesOfString:@"-"withString:@"/"];
结果: 2011/11/29
12.添加中划线
NSString *textStr = [NSString stringWithFormat:@"%@元", primeCost];
//中划线
NSDictionary *attribtDic = @{NSStrikethroughStyleAttributeName: [NSNumber numberWithInteger:NSUnderlineStyleSingle]};
NSMutableAttributedString *attribtStr = [[NSMutableAttributedString alloc]initWithString:textStr attributes:attribtDic];
// 赋值
strikeLabel.attributedText = attribtStr;
13.添加下划线:
NSString *textStr = [NSString stringWithFormat:@"%@元", primeCost];
// 下划线
NSDictionary *attribtDic = @{NSUnderlineStyleAttributeName: [NSNumber numberWithInteger:NSUnderlineStyleSingle]};
NSMutableAttributedString *attribtStr = [[NSMutableAttributedString alloc]initWithString:textStr attributes:attribtDic];
//赋值
underlineLabel.attributedText = attribtStr;
14.统一收起键盘
[[[UIApplication sharedApplication] keyWindow] endEditing:YES];
15.获取APP缓存大小,并清理
- (CGFloat)getCachSize {
NSUInteger imageCacheSize = [[SDImageCache sharedImageCache] getSize];
//获取自定义缓存大小
//用枚举器遍历 一个文件夹的内容
//1.获取 文件夹枚举器
NSString *myCachePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
NSDirectoryEnumerator *enumerator = [[NSFileManager defaultManager] enumeratorAtPath:myCachePath];
__block NSUInteger count = 0;
//2.遍历
for (NSString *fileName in enumerator) {
NSString *path = [myCachePath stringByAppendingPathComponent:fileName];
NSDictionary *fileDict = [[NSFileManager defaultManager] attributesOfItemAtPath:path error:nil];
count += fileDict.fileSize;//自定义所有缓存大小
}
// 得到是字节 转化为M
CGFloat totalSize = ((CGFloat)imageCacheSize+count)/1024/1024;
return totalSize;
}
13.清理APP缓存
- (void)handleClearView {
//删除两部分
//1.删除 sd 图片缓存
//先清除内存中的图片缓存
[[SDImageCache sharedImageCache] clearMemory];
//清除磁盘的缓存
[[SDImageCache sharedImageCache] clearDisk];
//2.删除自己缓存
NSString *myCachePath = [NSHomeDirectory() stringByAppendingPathComponent:@"Library/Caches"];
[[NSFileManager defaultManager] removeItemAtPath:myCachePath error:nil];
}
16.交换方法的实现
Class aClass = [self class];
SEL originalSelector = @selector(viewWillAppear:);
SEL swizzledSelector = @selector(xxx_viewWillAppear:);
Method originalMethod = class_getInstanceMethod(aClass, originalSelector);
Method swizzledMethod = class_getInstanceMethod(aClass, swizzledSelector);
BOOL didAddMethod =
class_addMethod(aClass,
originalSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(aClass,
swizzledSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
17.几个常用权限判断
if ([CLLocationManager authorizationStatus] ==kCLAuthorizationStatusDenied) {
NSLog(@"没有定位权限");
}
AVAuthorizationStatus statusVideo = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if (statusVideo == AVAuthorizationStatusDenied) {
NSLog(@"没有摄像头权限");
}
//是否有麦克风权限
AVAuthorizationStatus statusAudio = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
if (statusAudio == AVAuthorizationStatusDenied) {
NSLog(@"没有录音权限");
}
[PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
if (status == PHAuthorizationStatusDenied) {
NSLog(@"没有相册权限");
}
}];
18.升级cocoapods
在终端执行 sudo gem install -n / usr / local / bin cocoapods --pre
19.禁止手机睡眠
[UIApplication sharedApplication].idleTimerDisabled = YES;
20.导入自定义的字体库
1、找到你想用的字体的 ttf 格式,拖入工程
2、在工程的plist中增加一行数组,“Fonts provided by application”
3、为这个key添加一个item,value为你刚才导入的ttf文件名
4、直接使用即可:label.font = [UIFont fontWithName:@"你刚才导入的ttf文件名" size:20.0];
21.将tableview滚动到顶部
[tableView setContentOffset:CGPointZero animated:YES];
或者
[tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
22.自定义cell选中背景颜色
UIView *bgColorView = [[UIView alloc] init];
bgColorView.backgroundColor = [UIColor redColor];
[cell setSelectedBackgroundView:bgColorView];
23.UILabel设置文字描边
子类化UILabel,重写drawTextInRect方法
- (void)drawTextInRect:(CGRect)rect
{
CGContextRef c = UIGraphicsGetCurrentContext();
// 设置描边宽度
CGContextSetLineWidth(c, 1);
CGContextSetLineJoin(c, kCGLineJoinRound);
CGContextSetTextDrawingMode(c, kCGTextStroke);
// 描边颜色
self.textColor = [UIColor redColor];
[super drawTextInRect:rect];
// 文本颜色
self.textColor = [UIColor yellowColor];
CGContextSetTextDrawingMode(c, kCGTextFill);
[super drawTextInRect:rect];
}
24.手机摇一摇功能
1、打开摇一摇功能
[UIApplication sharedApplication].applicationSupportsShakeToEdit = YES;
2、让需要摇动的控制器成为第一响应者
[self becomeFirstResponder];
3、实现以下方法
// 开始摇动
- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
// 取消摇动
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
// 摇动结束
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
25.获取view的坐标在整个window上的位置
// v上的(0, 0)点在toView上的位置
CGPoint point = [v convertPoint:CGPointMake(0, 0) toView:[UIApplication sharedApplication].windows.lastObject];
或者
CGPoint point = [v.superview convertPoint:v.frame.origin toView:[UIApplication sharedApplication].windows.lastObject];
26.在非ViewController的地方弹出UIAlertController对话框
// 最好抽成一个分类
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Title" message:@"message" preferredStyle:UIAlertControllerStyleAlert];
//...
id rootViewController = [UIApplication sharedApplication].delegate.window.rootViewController;
if([rootViewController isKindOfClass:[UINavigationController class]])
{
rootViewController = ((UINavigationController *)rootViewController).viewControllers.firstObject;
}
if([rootViewController isKindOfClass:[UITabBarController class]])
{
rootViewController = ((UITabBarController *)rootViewController).selectedViewController;
}
[rootViewController presentViewController:alertController animated:YES completion:nil];
27.设置tableView分割线颜色
[self.tableView setSeparatorColor:[UIColor myColor]];
28.设置tableviewcell分割线顶到头
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
[cell setSeparatorInset:UIEdgeInsetsZero];
[cell setLayoutMargins:UIEdgeInsetsZero];
cell.preservesSuperviewLayoutMargins = NO;
}
- (void)viewDidLayoutSubviews {
[self.tableView setSeparatorInset:UIEdgeInsetsZero];
[self.tableView setLayoutMargins:UIEdgeInsetsZero];
}
29.在状态栏增加网络请求的菊花,类似safari加载网页的时候状态栏菊花
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
30.检查一个rect是否包含一个point
// point是否在rect内
BOOL isContains = CGRectContainsPoint(rect, point);
31.在指定的宽度下,让UILabel自动设置最佳font
自适应宽度
label.adjustsFontSizeToFitWidth = YES;
32.为一个View添加虚线边框
结合使用,效果更佳
CAShapeLayer *border = [CAShapeLayer layer];
border.strokeColor = [UIColor colorWithRed:67/255.0f green:37/255.0f blue:83/255.0f alpha:1].CGColor;
border.fillColor = nil;
border.lineDashPattern = @[@4, @2];
border.path = [UIBezierPath bezierPathWithRect:view.bounds].CGPath;
border.frame = view.bounds;
[view.layer addSublayer:border];
33.UITextView中打开或禁用复制,剪切,选择,全选等功能
// 继承UITextView重写这个方法
- (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
// 返回NO为禁用,YES为开启
// 粘贴
if (action == @selector(paste:)) return NO;
// 剪切
if (action == @selector(cut:)) return NO;
// 复制
if (action == @selector(copy:)) return NO;
// 选择
if (action == @selector(select:)) return NO;
// 选中全部
if (action == @selector(selectAll:)) return NO;
// 删除
if (action == @selector(delete:)) return NO;
// 分享
if (action == @selector(share)) return NO;
return [super canPerformAction:action withSender:sender];
}
34.UITableView 的删除操作,由于iOS11 手感的优化,出现了以下问题:
后来查明原因是最开始写代码的时候没有注意细节,在定义删除按钮的时候没有设置合适的类型:之前是 UITableViewRowActionStyleNormal,改为UITableViewRowActionStyleDestructive即可
原因:由于没有设置 删除 所特有的type,因此在UI展示上默认是不删除的,因此适配的是保留cell的UI,只有设置删除属性后,才能和deleteRowsAtIndexPaths方法保持UI上的同步
UITableViewRowAction *deleteRowAction = [UITableViewRowAction rowActionWithStyle:UITableViewRowActionStyleDestructive title:@"删除" handler:^(UITableViewRowAction *action, NSIndexPath *indexPath) {
[self.dataSource removeObjectAtIndex:indexPath.row];
// 刷新tableview
[self.tableView beginUpdates];
[self.tableView deleteRowsAtIndexPaths:@[ indexPath ] withRowAnimation:UITableViewRowAnimationAutomatic];
[self.tableView endUpdates];
}
35. 关于使用 iOS 中Instrument只显示地址不显示具体代码的问题
build setting中的Debug Information Forma在DEBUG下默认为DWARF,需要改为DWARF with dSYM File
36.使用collectionview 出现 Assertion failure in -[UICollectionViewData validateLayoutInRect:]
作者在使用collection滑动期间出现了上述问题,参考google解决方法先贴出来别人的解决方法
-(NSInteger )numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
[collectionView.collectionViewLayout invalidateLayout];
return 1;
}
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
[viewCollection.collectionViewLayout invalidateLayout];
}
collectionView.reloadData()
collectionView.collectionViewLayout.invalidateLayout()
override func prepare() {
self.invalidateLayout()
attributesArray.removeAll()
}
作者使用以上发现都无效,最后检查代码发现问题在于自定义UICollectionViewFlowLayout代码中存在问题,解决方法
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {}
let array = super.layoutAttributesForElements(in: rect)
这个方法中判断array
guard array?.count != 0 else {
return attributesArray
}
if array?.count != 0 && attributesArray.count != 0 {
return attributesArray
}
37. 侧滑返回手势与Scrollview冲突的解决办法,只需要在当前控制器加上几行代码就能解决这个问题
// 允许侧滑返回
let gestureArray = UIViewController.topMost?.navigationController?.view.gestureRecognizers
for gesture in gestureArray! {
if gesture.isKind(of: UIScreenEdgePanGestureRecognizer.classForCoder()) {
self.mainScrollView.panGestureRecognizer.require(toFail: gesture)
}
}
38. @discardableResult忽略警告
39. Assertion failure in -[UITableView _endCellAnimationsWithContext:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3698.93.8/UITableView.m:2062
这边使用如下代码出现崩溃
let indexSets = NSIndexSet.init(index: (tap.view?.tag)! - count)
mainTableView.reloadSections(indexSets as IndexSet , with: .automatic)
经过多方排查,找到问题在于两个对象内存地址一致导致刷新崩溃,
未修复崩溃前数据内存地址
第一条数据
(lldb) po dataSource
▿ 7 elements
▿ 0 :
▿ 1 :
▿ 2 :
▿ 3 :
▿ 4 :
▿ 5 :
▿ 6 :
(lldb) p dataSource
第二条数据
(lldb) po dataSource
▿ 10 elements
▿ 0 :
▿ 1 :
▿ 2 :
▿ 3 :
▿ 4 :
▿ 5 :
▿ 6 :
▿ 7 :
▿ 8 :
▿ 9 :
(lldb) p dataSource
处理崩溃,修改对象内存地址
第一条数据
(lldb) po dataSource
▿ 7 elements
▿ 0 :
▿ 1 :
▿ 2 :
▿ 3 :
▿ 4 :
▿ 5 :
▿ 6 :
(lldb)
第二条数据
▿ 10 elements
▿ 0 :
▿ 1 :
▿ 2 :
▿ 3 :
▿ 4 :
▿ 5 :
▿ 6 :
▿ 7 :
▿ 8 :
▿ 9 :
(lldb)