常用小知识点总结篇(持续更新)

目录
[TOC]

1 页面莫名被导航栏遮盖的解决办法

self.edgesForExtendedLayout = UIRectEdgeNone;
self.extendedLayoutIncludesOpaqueBars = NO;

2 收起键盘的四种方法

常用小知识点总结篇(持续更新)_第1张图片
image.png

3 textView字数限制

//在这个代理方法无法控制键盘联想
- (BOOL)textView:(YYTextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text {
    NSMutableString *newText = [NSMutableString stringWithString:textView.text];
    [newText replaceCharactersInRange:range withString:text];
    NSInteger strLength = textView.text.length - range.length + text.length;
    return (strLength <= 200);
}

//在这个代理方法监测长度,超过受限长度则截取
-(void)textViewDidChange:(YYTextView *)textView
{
    if (textView.text.length > 127) {
        textView.text = [textView.text substringToIndex:127];
    }else if(textView.text.length == 0) {
    }else {
    }
}

4 iOS 将自定义View添加到WebView上

要实现将self.topView放进self.webView里面随着webView的滑动一起滑动

    //先创建self.topView
    self.topView = [[YQZhidaoDetailTopView alloc] initWithDelegate:self WithModel:self.answer];
    //使用Frame创建一个承载的View top,**注意其y坐标**
    UIView *top = [[UIView alloc] initWithFrame:CGRectMake(0, -self.topView.topViewHeight, SCREEN_WIDTH, self.topView.topViewHeight)];
    [self.webView.scrollView addSubview:top];
    
    //将self.topView添加到top上,然后设置约束
    [top addSubview:self.topView];
    [self.topView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.mas_equalTo(UIEdgeInsetsZero);
    }];
//由于在webView上添加了一个头部,所以记得设置contentInset
self.webView.scrollView.contentInset = UIEdgeInsetsMake(self.topView.topViewHeight, 0, 0, 0);

5 xib的继承

关于xib的继承,分两种情况:1)子类无需修改xib 2)子类要在父类的xib上进行修改,下面分别说明使用方法
(1)子类无需修改xib,子类如何继承父类的样式?在子类中把initWithNibName:把此处改为父类的xib中的名字

- (instancetype)initWithNibName:(NSString )nibNameOrNil bundle:(NSBundle )nibBundleOrNil { 
      if (self = [super initWithNibName:@”父类的xib中的名字” bundle:nibBundleOrNil]) {
  } 
      return self; 
}

(2)子类需要在父类xib的基础上修改,子类如何既继承父类的样式,然后又能继承父类的业务逻辑处理?可以将父类的xib直接拖入到子类的xib中,直接在父类的xib中直接增加子类需要增加的UI元素(注意只能用拖入的方式,使用拷贝的方式会使得xib中的outlet失效),然后将子类xib的class文件改成对应的子类文件即可

常用小知识点总结篇(持续更新)_第2张图片
image.png
-(void)setModel:(ZhiDaoMixDataModel *)model
{
    //调用父类
    [super setModel:model];
    //子类需要处理的逻辑
    ....  
}

6 数组使用 valueForKeyPath:计算求和、平均值、最大、最小

NSArray *testArray = [NSArray arrayWithObjects:@"2.0", @"2.3", @"3.0", @"4.0", nil];
NSNumber *sum = [testArray valueForKeyPath:@"@sum.floatValue"];
NSNumber *avg = [testArray valueForKeyPath:@"@avg.floatValue"];
NSNumber *max = [testArray valueForKeyPath:@"@max.floatValue"];
NSNumber *min = [testArray valueForKeyPath:@"@min.floatValue"];

如果是数据模型对象:比如数据模型对象有一个属性 finishRate

CGFloat max = [[[self datas] valueForKeyPath:@"@max.finishRate"] floatValue];  

7 覆盖安装要注意的那些事

常用小知识点总结篇(持续更新)_第3张图片
image.png

8 layoutSubviews

  1. init初始化不会触发layoutSubviews
  2. 当view的fram的值为0的时候,addSubview不会调用layoutSubviews。
  3. addSubview的时候。
  4. 当view的frame发生改变的时候。
  5. 直接调用setNeedsLayout方法会调用。
  6. 滑动UIScrollView的时候。
  7. 旋转Screen会触发父UIView上的layoutSubviews事件。
  8. 改变一个UIView大小的时候也会触发父UIView上的layoutSubviews事件。

setNeedsLayout方法的意思是: 将调用者标记为需要重新布局,然后会异步调用layoutIfNeeded刷新布局,既然异步就不立即刷新,但layoutSubviews一定会被调用
layoutIfNeeded的意思是:当我被调用且被调用者有需要刷新的标记,则立即调用被调用者的layoutSubviews方法进行布局,如果被调用者没有被标记,layoutSubviews是不会被调用的。
另外就是,如果要立即刷新,要先调用[view setNeedsLayout],把标记设为需要布局,然后马上调用[view layoutIfNeeded],实现刷新布局。

9 关于[UIBarButtonItem alloc] initWithImage:颜色被冲的解决办法

UIImage *aimage = [UIImage imageNamed:@"xxx"];  
UIImage *image = [aimage imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal];  
UIBarButtonItem *rightItem = [[UIBarButtonItem alloc] initWithImage:image style:UIBarButtonItemStylePlain target:self action:@selector(action_rightClick:)];  
[self.navigationItem setRightBarButtonItem:rightItem animated:YES];  

10 手写tableViewCell时应该重写的初始化方法

- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 

11 tableview的header下拉粘滞效果实现

//让tableView往上延展20,以免状态栏部分是空白
self.tableView.contentInset = UIEdgeInsetsMake(-20, 0, 0, 0);

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    
    CGFloat contentOffsetY = scrollView.contentOffset.y;
    if (contentOffsetY <= 0) {
        self.bgTop.constant = contentOffsetY;
        CGFloat offsetWidth = rate* (-contentOffsetY);  //rate = backImgWidth/backImgheight
        self.bgLeading.constant = self.bgTrailing.constant = - offsetWidth / 2;
    }
}

12 Failed to send request for reason:Error Domain=NSURLErrorDomain Code=-1022 "The resource could not be loaded because the App Transport Security policy requires the use of a secure connection."

苹果公司要求所有接口使用https,错误原因就是这个。具体可在Info.plist里加入以下内容。

NSAppTransportSecurity
    
        NSAllowsArbitraryLoads
        
    

13 获取navigationController

// 假设 App 结构是 Root -> TabBar -> Navigation -> ViewController

UITabBarController *tabBarControler = (id)[UIApplication.sharedApplication.delegate.window.rootViewController;
UINavigationController *navigationController = tabBarControler.selectedViewController;

14 weak & strong self

/*
weakSelf是为了block不持有self,避免循环引用,而再声明一个strongSelf是因为一旦进入block执行,就不允许self在这个执行过程中释放。block执行完后这个strongSelf会自动释放,没有循环引用问题。
*/
 __weak __typeof(self)weakSelf = self;
self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{
    __strong __typeof(weakSelf)strongSelf = weakSelf;
}];

15 alertView、actionsheet修改按钮标题颜色

UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleActionSheet];
                    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
                    UIAlertAction *okAction = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDestructive handler:^(UIAlertAction *action){  
                    }];
[okAction setValue:UICOLOR_WITH_RGBINT(0xFF3B30) forKey:@"_titleTextColor"];  //主要是这句设置颜色

[alertController addAction:cancelAction];
[alertController addAction:okAction];
                    
[weakSelf presentViewController:alertController animated:YES completion:nil];

16 更改状态栏颜色

重写方法:

//设置字体颜色
- (UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleLightContent;//白色
}

然后在viewWillAppear里调用:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    [self preferredStatusBarStyle];
}

17 分类里增加属性

OC的分类允许给分类添加属性,但不会自动生成getter、setter方法。有没有解决方案呢?有,通过运行时建立关联引用。接下来以添加一个这样的属性为例,整体代码如下:

在匿名分类或者头文件中添加属性。区别是:匿名分类中添加的是私有属性,只在本类中可以使用,类的实例中不可以使用。头文件中添加的在类的实例中也可以使用。

//分类的头文件
@interface ClassName (CategoryName)
@property (nonatomic, strong) NSString *str;
@end

在实现里面写要添加属性的getter、setter方法。在setStr:方法中使用了一个objc_setAssociatedObject的方法,这个方法有四个参数,分别是:源对象,关联时的用来标记是哪一个属性的key(因为你可能要添加很多属性),关联的对象和一个关联策略。用来标记是哪一个属性的key常见有三种写法,但代码效果是一样的,如下:

//利用静态变量地址唯一不变的特性
1、static void *strKey = &strKey;
2、static NSString *strKey = @"strKey"; 
3、static char strKey;
关联策略是个枚举值,解释如下:
enum {
    OBJC_ASSOCIATION_ASSIGN = 0, //关联对象的属性是弱引用 
    OBJC_ASSOCIATION_RETAIN_NONATOMIC = 1, //关联对象的属性是强引用并且关联对象不使用原子性
    OBJC_ASSOCIATION_COPY_NONATOMIC = 3, //关联对象的属性是copy并且关联对象不使用原子性
    OBJC_ASSOCIATION_RETAIN = 01401, //关联对象的属性是copy并且关联对象使用原子性
    OBJC_ASSOCIATION_COPY = 01403 //关联对象的属性是copy并且关联对象使用原子性
};
//实现文件
#import "ClassName + CategoryName.h"
#import 
static void *strKey = &strKey;

@implementation ClassName (CategoryName)
-(void)setStr:(NSString *)str {
      objc_setAssociatedObject(self, & strKey, str, OBJC_ASSOCIATION_COPY);
}

-(NSString *)str {
      return objc_getAssociatedObject(self, &strKey);
}
@end

18 MJRefreshGifHeader

更换普通MJRefreshHeader的最简单的一个方式就是用一组图实现gif的效果:

MJRefreshGifHeader *header = [MJRefreshGifHeader headerWithRefreshingTarget:self refreshingAction:@selector(refreshData)];
//隐藏时间
header.lastUpdatedTimeLabel.hidden = YES;
//隐藏状态
header.stateLabel.hidden = YES;
        
NSMutableArray *idleImages = [NSMutableArray array];
for (NSInteger i=1; i<=6; i++) {
      UIImage *image = [UIImage imageNamed:[NSString stringWithFormat:@"ic_loading_0%li",(long)i]];
      [idleImages addObject:image];
}
//给MJRefreshStateIdle状态设置一组图片,可以是一张,idleImages为数组
 [header setImages:idleImages duration:1 forState:MJRefreshStatePulling];
[header setImages:idleImages duration:1 forState:MJRefreshStateRefreshing];
_tableView.mj_header = header;

还可以使用自己定义动画来实现:
具体参看利用MJRefresh定制自己的刷新动画

19 禁用textField出现复制粘贴剪切等操作

有时候我们需要禁用UITextField的双击出现copy、paste的功能,然而UITextField本身没有直接设置禁止用户复制粘贴剪切操作等方法,但是可以重载新建一个类继承UITextField,然后实现canPerformAction方法,只需覆盖canPerformAction:withSender方法就可以,canPerformAction:withSender属于UIResponder类的。

-(BOOL)canPerformAction:(SEL)action withSender:(id)sender {
    UIMenuController *menuController = [UIMenuController sharedMenuController];
    if (menuController) {
        [UIMenuController sharedMenuController].menuVisible = NO;
    }
    if (action == @selector(paste:))
        return NO;
    if (action == @selector(select:))
        return NO;
    if (action == @selector(selectAll:))
        return NO;
    if (action == @selector(cut:))
        return NO;
    if (action == @selector(copy:))
        return NO;
    return NO;
}

20 pragma 处理警告 clang diagnostic 的使用

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-相关命令"
    // 你自己的代码
#pragma clang diagnostic pop

常用相关命令有:

"-Wdeprecated-declarations"   //方法弃用告警
"-Wincompatible-pointer-types"    //不兼容指针告警
"-Warc-retain-cycles"   //循环引用告警
"-Wunused-variable"   //未使用变量告警
"-Wcovered-switch-default"  //未使用Default

pragma 处理警告 clang diagnostic 的使用

21 semanticContentAttribute

UIView下的一个属性,9.0系统及以上适用。用于页面RTL/LTR布局。

@property (nonatomic) UISemanticContentAttribute semanticContentAttribute NS_AVAILABLE_IOS(9_0);

typedef NS_ENUM(NSInteger, UISemanticContentAttribute) {
    UISemanticContentAttributeUnspecified = 0,
    UISemanticContentAttributePlayback, // for playback controls such as Play/RW/FF buttons and playhead scrubbers
    UISemanticContentAttributeSpatial, // for controls that result in some sort of directional change in the UI, e.g. a segmented control for text alignment or a D-pad in a game
    UISemanticContentAttributeForceLeftToRight,
    UISemanticContentAttributeForceRightToLeft
} NS_ENUM_AVAILABLE_IOS(9_0);
@property (nonatomic) UISemanticContentAttribute semanticContentAttribute NS_AVAILABLE_IOS(9_0);

平常我们常用的按钮是图标在左,标题在右。直接使用此属性便可更改左右位置。再借助于titleEdgeInsetsimageEdgeInsets便可轻松搞定布局。

_addBtn.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;
_addBtn.titleEdgeInsets = UIEdgeInsetsMake(0, -30, 0, 0);
_addBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 30, 0, 0);

22 UICollectionView的悬浮header

sectionHeadersPinToVisibleBounds同样是iOS9之后推出的特性。如果iOS9之前要实现UICollectionView的悬浮header需自定义layout。

UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
layout.scrollDirection = UICollectionViewScrollDirectionVertical;
layout.sectionHeadersPinToVisibleBounds = YES;

@property (nonatomic) BOOL sectionHeadersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);
@property (nonatomic) BOOL sectionFootersPinToVisibleBounds NS_AVAILABLE_IOS(9_0);

23 UIScrollview偏移问题

iOS11之前:

//在vc里写上
self.automaticallyAdjustsScrollViewInsets = NO;

iOS11之后:

if (@available(iOS 11.0, *)) {
        _tabelView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        self.automaticallyAdjustsScrollViewInsets = NO;
    }

大神写的:

#define  adjustsScrollViewInsets_NO(scrollView,vc)\
do { \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \
        if ([UIScrollView instancesRespondToSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:")]) {\
            [scrollView   performSelector:NSSelectorFromString(@"setContentInsetAdjustmentBehavior:") withObject:@(2)];\
        } else {\
            vc.automaticallyAdjustsScrollViewInsets = NO;\
        }\
    _Pragma("clang diagnostic pop") \
} while (0)

24 判断是否X以后的手机

判断是否为 iPhoneXS Max,iPhoneXS,iPhoneXR,iPhoneX

#define KIsiPhoneX ((int)((SCREEN_HEIGHTL/SCREEN_WIDTHL)*100) == 216)?YES:NO

25 UITableView上添加手势,与didSelect冲突


- (void)viewDidLoad {
    [self initTableView];
}
 
- (void) initTableView {
    UITableView *tableView = [[UITableView alloc] init];
    tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
    tableView.delegate = self;
    tableView.dataSource = self;
    tableView.backgroundColor = GCOLOR;
    tableView.showsVerticalScrollIndicator = NO;
    [self.view addSubview:tableView];
    [tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.right.mas_equalTo(0);
        make.top.mas_equalTo(0);
        make.bottom.mas_equalTo(iPhoneX ? @-84 : @-50);
    }];
    self.tableView = tableView;
    
    //区头高度
    if (@available(iOS 11.0, *)) {
        self.tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        // est和代理 可选1个
        self.tableView.estimatedSectionHeaderHeight = 10;
    } else {
        self.automaticallyAdjustsScrollViewInsets = NO;
    }
    //table添加手势点击
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];
    tap.delegate = self;
    [tableView addGestureRecognizer:tap];
}
 
#pragma mark - 手势代理
//table添加手势
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([NSStringFromClass([touch.view class]) isEqualToString:@"UITableViewCellContentView"]) {
        return NO;
    } else {
        self.cxHelpV.hideView = YES;
        return YES;
    }

26 将button的点击区域限定在selectView里

//将button的点击区域限定在selectView里

  • (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
    //首先调用父类的方法确定点击的区域确实在按钮的区域中
    BOOL res = [super pointInside:point withEvent:event];
    if (res) {
    //绘制一个圆形path
    UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:self.selectView.bounds];
    if ([path containsPoint:point]) {
    //如果在path区域内,返回YES
    return YES;
    }
    return NO;
    }
    return NO;
    }

27 放大

weakSelf.countDown.transform = CGAffineTransformMakeScale(1.5, 1.5);//放大值
weakSelf.aphView.transform = CGAffineTransformMakeScale(10, 10);//放大值

28 pod使用某个分支

pod 'SDJGCommunityProject',:git=>'http://192.168.0.224/iosenterprise/staffApp_sdjgcommunityproject.git',:branch=>'br_fix_SWHomePageAdPopViews_1.2.5'

29 cocoapods的卸载和安装

卸载cocoapods
sudo gem uninstall cocoapods

安装
sudo gem install -n /usr/local/bin cocoapods -v 1.7.5
安装最新版本
sudo gem install -n /usr/local/bin cocoapods --pre

30 iOS 13tabbar隐藏黑线、隐藏背景等

https://blog.csdn.net/Goods_boy/article/details/102862642

31 Button 标题和icon位置互换

_moreButton.semanticContentAttribute = UISemanticContentAttributeForceRightToLeft;

32 自定义字体库

ios - 添加自定义字体库

    NSArray *arr = [UIFont familyNames];
    NSInteger i = 0;
    for (NSString *str in arr) {
        NSArray *arr_01 = [UIFont fontNamesForFamilyName:str];
        for (NSString *str_01 in arr_01) {
            NSLog(@"%i:%@",i,str_01);
            i++;
        }
    }

33 安装了conda后,前面会有一个(base)

mac安装了conda后,前面会有一个(base),很烦人,终于找到最佳解决方案了:

$ conda config --set auto_activate_base false

原因:

安装conda后,每次启动终端,都会自动启动conda的base环境,conda的环境可以用 conda env list 查看

只要设置conda不要自动启动base环境就可以了。

你可能感兴趣的:(常用小知识点总结篇(持续更新))