iOS开发笔记

本笔记用于记录IOS学习和开发中遇到的经验和技巧。


  1. 在xcode中增加 Duplicate Current Line 的快捷键:
    1
    2
    3
    4
    5
    6
    7
    #1) 修改权限:
    sudo chmod 666 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/IDETextKeyBindingSet.plistsudo chmod 777 /Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/
    #2) 打开plist文件:
    open/Applications/Xcode.app/Contents/Frameworks/IDEKit.framework/Resources/IDETextKeyBindingSet.plist
    #3) 在Insertions and Indentations中添加:
    <key>Duplicate Current Line</key>
    <string>selectLine:, copy:, moveToEndOfLine:, insertNewline:, paste:, deleteBackward:, moveToBeginningOfLine:, deleteBackward:, moveToEndOfLine:</string>
  2. 剪切ImageView超出部分
    1
    2
    //设置这个属性为YES就可以了,默认是NO;
    imgeView.clipstobounds = YES;
  3. 枚举类型定义:
    1
    2
    3
    4
    5
    6
    typedef NS_ENUM(NSInteger, SHMPersonalCenterLoginType) {
    SHMPersonalCenterLoginTypePhone,
    SHMPersonalCenterLoginTypeQQ,
    SHMPersonalCenterLoginTypeWechat,
    SHMPersonalCenterLoginTypeWeibo,
    };
  4. 给 UIview 添加手势:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    view.tag = i;
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(columnDidSelected:)];
    [view addGestureRecognizer:tap];

    // 下方响应函数
    - (void)columnDidSelected:(UITapGestureRecognizer*)tap{
    UIView *view = (UIView *)tap.view;
    [self.homePageRecommandViewModel.pushVCCommand execute:self.homePageRecommandViewModel.homePageColumnsArray[view.tag].url];
    }
  5. xcode 开启兼容模式(小锤子):
    1
    File => workspace setting => build system => legacy build system
  6. xcode signing显示 xxx has conflicting provisioning settings.错误:

    1
    2
    3
    4
    解决方法
    1 打开buiild setting -> code signing Entitlements 删除已有信息
    2 打开"项目名.xcodeproj"然后右键显示包内容,打开:project.pbxproj
    3 搜索xxx这个数字(错误原因的这一串字符),删除之,即可(这个数字在引号中间,不要删除引号及引号外的字符。)
  7. 利用runtime获取方法名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    unsigned int methCount = 0;
    Method *meths = class_copyMethodList([UIDatePicker class], &methCount);
    for (int i = 0 ; i < methCount; i++) {
    Method meth = meths[i];
    SEL sel = method_getName(meth);
    const char *name = sel_getName(sel);
    NSLog(@"%s",name);
    }
    free(meths);
  8. NSURLError.h里面包含了很多常见的url错误编码
    1
    2
    3
    4
    5
    6
    7
    8
    NS_ERROR_ENUM(NSURLErrorDomain)
    {
    NSURLErrorUnknown = -1,
    NSURLErrorCancelled = -999,
    NSURLErrorBadURL = -1000,
    NSURLErrorTimedOut = -1001,
    ……
    };
  9. iOSAPP开启时判断通过何种方式开启
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    - (void)setupViewWithOptions:(NSDictionary *)launchOptions {
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen sh_bounds]];
    SHMStartScreenModel *model = [[SHMAppManager sharedInstance] showStartScreen];
    SHMTabBarController *tab = [[SHMTabBarController alloc] init];

    BOOL pushOrOpenURL = NO;
    // 这里直接判断launchOptions是否为空即可:
    // 如果是快捷指令打开的UIApplicationLaunchOptionsUserActivityTypeKey是设置好的ActivityType
    // 如果是web打开的UIApplicationLaunchOptionsUserActivityTypeKey为NSUserActivityTypeBrowsingWeb
    // 如果是推送打开的UIApplicationLaunchOptionsRemoteNotificationKey是一个字典
    if (launchOptions) {
    pushOrOpenURL = YES;
    }
    }
  10. TableViewCell中嵌套TextView,实现动态高度

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    // 第一步:设置合理的布局,撑开cell
    [self.inputInfoTextView mas_makeConstraints:^(MASConstraintMaker *make) {
    make.top.equalTo(self.contentView).offset(22).priority(900);
    make.left.equalTo(self.contentView).offset(127);
    make.right.equalTo(self.contentView).offset(-35);
    make.bottom.equalTo(self.contentView).offset(-22).priority(800);
    make.height.mas_greaterThanOrEqualTo(20).priority(700);
    }];
    // 第二步:计算TextView高度并更新布局
    CGSize textViewSize = CGSizeMake(self.inputInfoTextView.frame.size.width, CGFLOAT_MAX);
    CGSize finalSize = [self.inputInfoTextView sizeThatFits:textViewSize];
    if (finalSize.height != self.inputInfoTextView.frame.size.height) {
    [self.inputInfoTextView mas_updateConstraints:^(MASConstraintMaker *make) {
    make.height.mas_greaterThanOrEqualTo(finalSize.height);
    }];
    [self layoutIfNeeded];
    // 第三步:通知tableview刷新布局
    if ([self.superview isKindOfClass:UITableView.class]) {
    UITableView *superTableView = (UITableView *)self.superview;

    if (@available(iOS 11.0, *)) { // iOS11.0以后新系统用 performBatchUpdates 方法来替代 beginUpdates/endUpdates
    [superTableView performBatchUpdates:nil completion:nil];
    } else {
    [superTableView beginUpdates];
    [superTableView endUpdates];
    }

    }
    }
  11. contentModeAspectFit的UIImageView 如何得到实际展示的图片尺寸

    1
    CGRect rect = AVMakeRectWithAspectRatioInsideRect(self.originalImage.size,imageView.frame);
  12. UITableView的superView并不总是UITableView。在iOS12 or 11以下,superView是UITableViewWrapperView;所以对于cell,想要获取superTableView可以如下实现:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    - (UITableView *)shmp_parentTableView {
    if ([self.superview isKindOfClass:UITableView.class]) {
    return (UITableView *)self.superview;
    } else if ([self.superview.superview isKindOfClass:UITableView.class]) {
    return (UITableView *)self.superview.superview;
    } else {
    return nil;
    }
    }
  13. UITableView的register方法,回导致dequeue方法的cell不为空

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [_mainTableView registerClass:SHMPHomeArticleCell.class forCellReuseIdentifier:NSStringFromClass(SHMPHomeArticleCell.class)];
    [tableView dequeueReusableCellWithIdentifier:identifier];

    // 所以如果要利用ViewModel进行初始化,则需要使用下面这种形式
    SHMPTableViewEmptyCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(SHMPTableViewEmptyCell.class)];
    if (!cell) {
    cell = [[SHMPTableViewEmptyCell alloc] initWithViewModel:nil identifier:NSStringFromClass(SHMPTableViewEmptyCell.class)];
    }
    [cell updateUIWithIdentifier:NSStringFromClass(SHMPTableViewEmptyCell.class)];
    return cell;
  14. UIView包含需要被点击的组件,所以userInteractEnabled必须设为YES,但是UIView盖在其他需要被点击的组件上面,此时需要设置hitTest:

    1
    2
    3
    4
    5
    6
    7
    - (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent *)event{
    UIView *hitView = [super hitTest:point withEvent:event];
    if(hitView == self){
    return nil;
    }
    return hitView;
    }
  15. iOS系统默认字体

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    // iOS系统默认字体是SFUIText,是苹方的英文字体,如果使用
    [UIFont systemFontOfSize:20 weight:UIFontWeightMedium]

    // 直接设置,则中文字体不生效,需要指定苹方的中文字体名
    [UIFont fontWithName:@"PingFangTC-Semibold" size:20];

    /*
    具体名字包括:
    1. PingFangTC-Regular
    2. PingFangTC-Thin
    3. PingFangTC-Medium
    4. PingFangTC-Semibold
    5. PingFangTC-Light
    6. PingFangTC-Ultralight
    */