iOS一些小技巧 | 三

一,UIButton让其文字在图片下方:

[operateBt setTitleEdgeInsets:UIEdgeInsetsMake(operateBt.imageView.frame.size.height+14.0, -operateBt.imageView.frame.size.width, 0.0, 0.0)];
[operateBt setImageEdgeInsets:UIEdgeInsetsMake(0.0, 0.0, 0.0, -operateBt.titleLabel.bounds.size.width)];

二,UIButton用SF符号:

        let image = UIImage(named: "record_def_svg")
        
        var config = UIImage.SymbolConfiguration(font: systemFontWithSize(ScaleSize(152.0)));
        if #available(iOS 15.0, *) {
            config = config.applying(UIImage.SymbolConfiguration(paletteColors: [.white]));
        }else {
            image?.withTintColor(.white, renderingMode: .alwaysOriginal);
        }
        image?.withTintColor(.white, renderingMode: .alwaysTemplate);
        recordButton.setImage(image, for: .normal);
        recordButton.setPreferredSymbolConfiguration(config, forImageIn: .normal);

3,主线程返回一个值:

- (BOOL)isBool {
    __block BOOL result;
    if ([NSThread isMainThread]) {
        return YES;
    } else {
        dispatch_sync(dispatch_get_main_queue(), ^{
            result = YES;
        });
    }
    return result;
}

4,willMoveToSuperview,view的方法,view即将添加到superview或者即将被移除的时候调用,例如:

- (void)willMoveToSuperview:(UIView *)newSuperview
{
    if(newSuperview != nil){
        self.bounds = CGRectMake(0.0, 0.0, self.bounds.size.width, self.collectionViewLayout.collectionViewContentSize.height);
    }
    [super willMoveToSuperview:newSuperview];
}

5,UISearchController取消按钮更改其title:

        searchController.searchBar.showsCancelButton = true;
        if let subFirst = searchController.searchBar.subviews.first,searchController.isActive {
            let searchBarContainerView = subFirst.subviews[1];
            for barSuvViews in searchBarContainerView.subviews {
                if barSuvViews.isKind(of: UIButton.self){
                    let cancelButton: UIButton = barSuvViews as! UIButton;
                    cancelButton.setTitle("取消", for: .normal);
                }
            }
        }

6,URL格式化和反格式化:

//格式化URL
+(NSString *)encodeUrl:(NSString *)sourceURL
{
    if (System_Version_Later(9.0)) {
        return [sourceURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }else{
        return [sourceURL stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"`#%^{}\"[]|\\<> "].invertedSet];
    }
}

//反格式化ULR
- (NSString *)decodeUrl:(NSString *)codeURL
{
    if (System_Version_Later(9.0)) {
        return [codeURL stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    }else{
        return [codeURL stringByRemovingPercentEncoding];
    }
}

七,deviceToken,NSData类型转NSString。

    NSString *strToken;
    //Xcode11打的包,iOS13获取Token有变化
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 13) {
        if (![deviceToken isKindOfClass:[NSData class]]) {
            //记录获取token失败的描述
            return;
        }
        const unsigned *tokenBytes = (const unsigned *)[deviceToken bytes];
        strToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x",
                              ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]),
                              ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]),
                              ntohl(tokenBytes[6]), ntohl(tokenBytes[7])];
    
        NSLog(@"deviceToken1:%@", strToken);
    } else {
        strToken = [NSString
                           stringWithFormat:@"%@",deviceToken];
        strToken = [strToken stringByReplacingOccurrencesOfString:@"<" withString:@""];
        strToken = [strToken stringByReplacingOccurrencesOfString:@">" withString:@""];
        strToken = [strToken stringByReplacingOccurrencesOfString:@" " withString:@""];
        NSLog(@"deviceToken2 is: %@", strToken);
    }

八,OC自定义struct。

struct
Sky_Location {
    CGFloat top;
    CGFloat left;
    CGFloat right;
};
typedef struct CG_BOXABLE Sky_Location Sky_Location;

CG_INLINE Sky_Location
Sky_LocationMake(CGFloat top, CGFloat left, CGFloat right)
{
    Sky_Location location; location.top = top; location.left = left; location.right = right; return location;
}

九,自定义View当中,因为使用了延迟调用,例如:
[self performSelector:@selector(countdown) withObject:nil afterDelay:30.0]而导致dealloc不去执行,可在didMoveToSuperview中取消执行selector,可取消引用从而调用dealloc,如下:

//当view加入或离开superview时,调用此方法
- (void)didMoveToSuperview
{
    NSLog(@"didMoveToSuperview");
    if(nil == self.superview){
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(countdown) object:nil];
        [NSObject cancelPreviousPerformRequestsWithTarget:self selector:@selector(display) object:nil];
    }
}

十,模拟数组循环;

- (void)foreachWithOperate:(void( ^ _Nullable)(id _Nonnull object,NSInteger idx,bool *stop))operate
{
    for (NSInteger i = 0; i < self.count - 1; i++) {
        bool isStop = NO;
        if(operate) {
            operate(self[i],i,&isStop);
        }
        if(YES == isStop) {
            break;
        }
    }
}

十一,以动画的方式刷新tableview。

[UIView transitionWithView:weakSelf.detatilInfoTabView duration: 0.55f options: UIViewAnimationOptionTransitionFlipFromLeft animations: ^(void){
      [weakSelf.detatilInfoTabView reloadData];
}completion:^(BOOL finished) {
      dispatch_async(dispatch_get_main_queue(), ^{
            [weakSelf addFooterViewByAD];
      });
}];

十二,UITextView加载富文本,其资源文件过大导致卡顿的解决办法。

[NSThread detachNewThreadWithBlock:^{
                //
      NSString *jieShaoDetail = [NSString stringWithFormat:@"<head><style>img{width:%f !important;height:auto}</style></head>%@", (ScreenWidth-ScaleForSize(40.0)*2), detailModel.intro];
      NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:[jieShaoDetail dataUsingEncoding:NSUnicodeStringEncoding] options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:nil];
      dispatch_async(dispatch_get_main_queue(), ^{
           weakSelf.jieshaoTextView.attributedText = attributedString;
           [weakSelf.bgScrollView layoutIfNeeded];
           weakSelf.bgScrollView.contentSize = CGSizeMake(0.0, weakSelf.yuYueTextView.bottom + ScaleForSize(40.0) + ScaleForSize(100.0));
      });
}];

十三,addChildViewController子控制器之后,要修改子控制器的frame,需要如下:

//父控制器中:
IMSearchInitPageController *siCtrl = [[IMSearchInitPageController alloc]init];
siCtrl.view.frame = CGRectMake(0.0, naviBarHeight, ScreenWidth, ScreenHeight - naviBarHeight);
[self addChildViewController:siCtrl];
[self.view addSubview:siCtrl.view];
//自控制器中修改self.view的大小,重写loadView方法 - 重写self.view
- (void)loadView
{
    self.view = [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, ScreenWidth, ScreenHeight - navigationBarHeight - 8)];
}

十四,根据父类的宽度进行约束,并且在父类的基础上增加一些数值:

//让其view在父类宽度 * 0.7的基础上,增加navigationDisparityHeight的高度。
[self.coverView mas_makeConstraints:^(MASConstraintMaker *make) {
      (void)make.top.left.right;
           make.height.mas_equalTo(self.mas_width).multipliedBy(0.7).offset(navigationDisparityHeight);
}];

十五,在不知道宽高确切数值的情况下,约束宽高相同。

        [self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
            make.top.mas_equalTo(ScaleForLengthWith2(10.0));
            make.right.bottom.mas_equalTo(-ScaleForLengthWith2(10.0));
            make.width.mas_equalTo(self.imageView.mas_height);
        }];

十六,获取label的高度:

//
CGSize descSize = [self.descLable sizeThatFits:CGSizeMake(ScreenWidth-ScaleForSize(60.0)*2, 0.0)];
//

十七,masonry动画:

//
    [cateUnfoldView layoutIfNeeded];
    //
    [UIView animateWithDuration:0.2 animations:^{
        [cateUnfoldView.cateListView mas_updateConstraints:^(MASConstraintMaker *make) {
            make.height.mas_equalTo(datas.count*ScaleForSize(70.0));
        }];
        [cateUnfoldView layoutIfNeeded];
    }];
//

十八,UIImage图片翻转;因拍照时,可能导致UIImage90度翻转,需要进行判断且翻转,然后上传到后台使用:

//
//
UIImage *uploadImage = xxx;
if(uploadImage.imageOrientation == UIImageOrientationRight){
   UIImage *realImage = [UIImage imageWithCGImage:backImage.image.CGImage scale:backImage.image.scale orientation:UIImageOrientationLeftMirrored];
}
if(uploadImage.imageOrientation == UIImageOrientationLeft){
   UIImage *realImage = [UIImage imageWithCGImage:backImage.image.CGImage scale:backImage.image.scale orientation:UIImageOrientationRightMirrored];
}
//realImage为最终图片
//
//

Leave a Reply

Your email address will not be published. Required fields are marked *