专栏首页進无尽的文章实践-小细节Ⅵ

实践-小细节Ⅵ


1. UITableView的空白区域颜色设置

有时候,UITableView 的cell个数很少,可是UITableView的headView又是一个有颜色背景的View,当我们下拉的时候,拉扯出来的区域也是白色的,很不协调

解决办法: _Tb.backgroundColor=litteGray;

设置 _Tb.backgroundColor = [UIColor ClearColor]。想通过设置 _Tb的父视图的背景颜色来达到想象的效果是行不通的。

2. 关于UISearchBar 的设置以及取消按钮的颜色和文字设置

效果图

    UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(Scale_X(20), Scale_Y(10), self.bounds.size.width-Scale_X(40), Scale_Y(36))];
        searchBar.placeholder = @"请输入搜索关键字";
        searchBar.showsCancelButton = YES;
        searchBar.delegate =self;
        searchBar.layer.cornerRadius=4;
        searchBar.clipsToBounds = YES;  //不设置的话没有圆角
        searchBar.delegate = self;
        [searchBar setBackgroundImage:[UIImage imageNamed:@"sousuoBg"]];
        [searchBar setSearchFieldBackgroundImage:[UIImage imageNamed:@"sousuoBg"] forState:UIControlStateNormal];
        searchBar.tintColor  =[UIColor lightGrayColor];
        //亲测有效
        [[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTintColor:[UIColor blackColor]];
        [[UIBarButtonItem appearanceWhenContainedIn: [UISearchBar class], nil] setTitle:@"取消"];

修改UISearchBar 的placeholder的字体颜色和大小 有两种方法,不过要注意的是要写在最后面,之前就是因为写在最前面被覆盖导致无效果的。

第一种  
    [[UITextField appearanceWhenContainedIn: [UISearchBar class], nil] setFont:[UIFont boldSystemFontOfSize:10]];
第二种  
    UITextField * searchField = [searchBar valueForKey:@"_searchField"];
    [searchField setValue:GrayTextColor forKeyPath:@"_placeholderLabel.textColor"];
    [searchField setValue:[UIFont boldSystemFontOfSize:10] forKeyPath:@"_placeholderLabel.font"];

    [self addSubview:searchBar];


   #pragma mark - UISearchBarDelegate
    -(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
    {
        //从本地数据库中模糊查找
        NSString *sql = [NSString stringWithFormat:@"select * from t_contact where name like '%%%@%%'", searchText];
        _dataArray = (NSMutableArray *)[CGContactTool contactWithSql:sql];
        
        [self.Tb reloadData];
    }

    - (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
    {
        [self endEditing:YES];
    }

    - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
    {
        [self endEditing:YES];
    }

3. 对于这样复杂页面的绘制心得

    NSArray *titleA = @[@"企业名称:",@"营业执照编码:",@"营业资格证编号:",@"法人代表:",@"联系地址:",
                        @"企业负责人:",@"联系方式:",@"营业执照照片:",@"许可证照片:",@"安全管理员姓名:",
                        @"安全管理员电话:",@"安全管理员证书:",@"安全管理员证书等级:",@"安全系统监控:",@"安全员培训机构:"];
    
    for (int i = 0; i<titleA.count; i++) {
        
        UILabel *titlelabel  = [[MethodTool shareTool] creatLabelWithAttribute:[titleA objectAtIndex:i] :MEDIUM_FONT :1 :GrayTextColor];
        [self addSubview:titlelabel];
        CGFloat labelWidth = [[MethodTool shareTool]getWidthWithString:titlelabel.text anfont:MEDIUM_FONT];
        if (i<8) {
            titlelabel.sd_layout.leftSpaceToView(self,Scale_X(25)).topSpaceToView(selectV,Scale_Y(i*45)).widthIs(labelWidth).heightIs(i==7?Scale_Y(100):Scale_Y(45));
        }else if (i==8){
            titlelabel.sd_layout.leftSpaceToView(self,Scale_X(25)).topSpaceToView(selectV,Scale_Y((i*45+55))).widthIs(labelWidth).heightIs(Scale_Y(100));
        }else if (i<12){
            titlelabel.sd_layout.leftSpaceToView(self,Scale_X(25)).topSpaceToView(selectV,Scale_Y((i*45+110))).widthIs(labelWidth).heightIs(i==11?Scale_Y(100):Scale_Y(45));
        }else{
            titlelabel.sd_layout.leftSpaceToView(self,Scale_X(25)).topSpaceToView(selectV,Scale_Y((i*45+165))).widthIs(labelWidth).heightIs(Scale_Y(45));
        }
       
        
        
        if (i!= 7||i!= 8||i!= 11||i!= 12||i!= 13) {
            
            rightTextLablel[i]  = [[OSTextField alloc]init];
            rightTextLablel[i] = [[OSTextField alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
            rightTextLablel[i].backgroundColor = [UIColor clearColor];
            if (i != 2) {
                rightTextLablel[i].keyboardType = UIKeyboardTypeDecimalPad;
            }
            rightTextLablel[i].superView = [[MethodTool shareTool]backActiveViewController].view;
            rightTextLablel[i].placeholder = @"";
            [rightTextLablel[i] setValue:[UIColor whiteColor] forKeyPath:@"_placeholderLabel.textColor"];
            [rightTextLablel[i] setValue:[UIFont fontWithName:@"Helvetica" size:16.0] forKeyPath:@"_placeholderLabel.font"];
            rightTextLablel[i].prompts = [titleA objectAtIndex:i];
            [rightTextLablel[i] initTopView];
            [rightTextLablel[i] limitTextLength:10];
            rightTextLablel[i].block = ^ {
                
            };
            [self addSubview:rightTextLablel[i]];
            rightTextLablel[i].sd_layout
            .leftSpaceToView(titlelabel,Scale_X(10))
            .topEqualToView(titlelabel)
            .rightSpaceToView(self, Scale_X(10))
            .heightIs(Scale_Y(45));
        }
        
        UIView *lineV = [UIView new];
        [self addSubview:lineV];
        lineV.backgroundColor = ViewlineColor;
        lineV.sd_layout
        .leftSpaceToView(self,Scale_X(15))
        .topSpaceToView(titlelabel,0)
        .rightSpaceToView(self, Scale_X(15))
        .heightIs(Scale_Y(1));
        
        
        
        //*********************************************************************************
        
        
        if (i<11) {
            [[MethodTool shareTool]addStarImageForView:self  :titlelabel];
        }
        
        if (i==7||i==8||i==11) {
            UIButton *selectImage = [[MethodTool shareTool]creatButtonWithAttribute:@"" :BIG_FONT :[UIColor clearColor] :RGB(252,36,85,1)];
            [self addSubview:selectImage];
            [selectImage setBackgroundImage:[UIImage imageNamed:@"addGrayImage"] forState:UIControlStateNormal];
            selectImage.sd_layout.centerYEqualToView(titlelabel).leftSpaceToView(self, Scale_X(150)).widthIs(Scale_X(80)).heightIs(Scale_Y(80));
            [selectImage addTarget:self action:@selector(submitTask) forControlEvents:UIControlEventTouchUpInside];
        }
        
        
        if (i==12||i==13) {
            
            BIShowPopViewSelect *selectV1 = [[BIShowPopViewSelect alloc]initWithFrame:CGRectMake(0, 0, Scale_X(130), Scale_Y(35)) :i==12?@"初级":@"否" :i==12?@"初级":@"否"];
            [self addSubview: selectV1];
            selectV1.sd_layout.leftSpaceToView(self,i<9?Scale_X(130):Scale_X(200)).centerYEqualToView(titlelabel).widthIs(Scale_X(120)).heightIs(Scale_Y(34));
        }
    }

可以看到整个逻辑都是在 For 循环中判断的,控件的Frame设置,主要是对 Lable的位置作逻辑判断,其他的其周围的控件都根据当前 i 下的 label 的位置来设定自己的位置。 所以只要设定好 每一个 i 下的 Label的位置,其他的控件位置就定了,这样最简单

在此基础上可以把这样复杂的页面完成设置成互相依赖,最后再单个视图赋值高度,整个视图就很方便的变了。

 for (int i = 0; i<titleArray.count; i++) {
    
    textLabel[i]  = [[MethodTool shareTool] creatLabelWithAttribute:titleArray[i] :MEDIUM_FONT :1 :blackC];
    [self.sc addSubview:textLabel[i]];
    textLabel[i].numberOfLines = 0;
    textLabel[i].sd_layout
    .leftSpaceToView(self.sc,Scale_X(45))
    //这是关键所在
    .topSpaceToView(i==0?self.sc:textLabel[i-1],Scale_Y(10))
    .widthIs(Scale_X(270))
    .heightIs(Scale_Y(45));

    
    CGFloat height = [[MethodTool shareTool]changeStationWidth:textLabel[i].text anWidthTxtt:Scale_X(270) anfont:MEDIUM_FONT];
    textLabel[i].sd_layout.heightIs((height));

    UILabel *indexLabel  = [[MethodTool shareTool] creatLabelWithAttribute:[NSString stringWithFormat:@"%d、",i+1] :MEDIUM_FONT :1 :blackC];
    [self.sc addSubview:indexLabel];
    indexLabel.sd_layout
    .rightSpaceToView(textLabel[i],Scale_X(0))
    .centerYEqualToView(textLabel[i])
    .widthIs(Scale_X(30))
    .heightIs(Scale_Y(45));
    
    selectButton[i] = [[LMForSelecSmallView alloc]initWithFrame:CGRectMake(0, 0, Scale_X(25), Scale_X(25))];
    [self.sc addSubview:selectButton[i]];
    selectButton[i].sd_layout
    .leftSpaceToView(textLabel[i],Scale_X(10))
    .centerYEqualToView(textLabel[i])
    .widthIs(Scale_X(25))
    .heightIs(Scale_Y(25));
    
}

重置self.sc 的ContentSize; AddNewImageAndVideoV 是sc的底部视图

[AddNewImageAndVideoV updateLayout];
[self.sc setContentSize:CGSizeMake(WIDTH, AddNewImageAndVideoV.origin.y+AddNewImageAndVideoV.frame.size.height)];

4. 动态添加高度很高的Cell

使用UIView动画实现:

 //动态移动
[UIView animateWithDuration:0.6 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{
    [Tb setContentOffset:CGPointMake(0,cellHeight*(cellNumebr-1))];
} completion:^(BOOL finished) {}];

使用SDK的动画效果实现:

 [Tb setContentOffset:CGPointMake(0, cellHeight*(cellNumebr-1)) animated:YES];

细心的可能已经看出来了,直接使用 - (void)setContentOffset:(CGPoint)contentOffset animated:(BOOL)animated;会在拉到顶部再次添加的时候流畅的滚动到底部,而不是这个 API只设置 setContentOffset 相当于是设置了属性值,从这可以看出,使用系统的带有 animated:(BOOL)animated; 的方法有时候可以实现很舒服强大的效果。

5. 实现description方法 打印出Model属性

1504837291574293.jpg

我们发现在我自己创建的类中,没有实现description 和debugDescription 我们会发现 但我们 log 出来和po 出来的仅仅是一个内存地址,这样对我们查看model 里面的字段是很不方便的,因此我们需要打印属性的类建议实现这个方法,举个例子如果我们想查看对请求的model 打log,那么可以在BaseModel 加上

- (NSString *)description {    
        return [NSString stringWithFormat:@"%@",[self mj_keyValues]];
}
- (NSString *)debugDescription {   
        return   [NSString stringWithFormat:@"%@ -- %p",[self mj_keyValues], self];
}

那么便可以方便的查看log 和debug 时打印出属性如图

1504837404190908.jpg

6. 版本的检测更新提示

-(void)hsUpdateApp
{
    //2先获取当前工程项目版本号
    //    NSDictionary *infoDic=[[NSBundle mainBundle] infoDictionary];
    //    NSString*currentVersion=infoDic[@"CFBundleShortVersionString"];
    
    //  如果当前提交的代码  Version大于商店要发布的版本,那就不从本地去版本,直接写死版本号为商店要发布的版本
    NSString *currentVersion = @"1.8.2";

    //3从网络获取appStore版本号
    NSOperationQueue *queue = [NSOperationQueue new];
    [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:[NSString
                                                                                                stringWithFormat:@"http://itunes.apple.com/cn/lookup?id=%@",@"1026XXXXX"]]] queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
        
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (data == nil) {
                NSLog(@"你没有连接网络哦");
                return;
            }
            NSError *error = nil;
            NSDictionary *appInfoDic = [NSJSONSerialization JSONObjectWithData:data
                                                                       options:NSJSONReadingMutableLeaves error:&error];
            if (error) {
                NSLog(@"hsUpdateAppError:%@",error);
                return;
            }
            NSArray *array = appInfoDic[@"results"];
            NSDictionary *dic =  array[0];
            appStoreVersion = dic[@"version"];
            
            //打印版本号
            NSLog(@"当前版本号:%@\n商店版本号:%@",currentVersion,appStoreVersion);
            //4当前版本号小于商店版本号,
            
            if([self compareEditionNumber:appStoreVersion localNumber:currentVersion])
            {
                  // 如果商店版本号和本地保存的跳过的版本号不一样就更新
                    (因为商店版本号>=本地保存的跳过的版本号)
                if (![[[MethodTool shareTool] getUserDefaults:@"appStoreVersion"] isEqualToString:appStoreVersion]) {
                    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"版本有更新"
                                                                    message:[NSString stringWithFormat:@"检测到新版本(%@),是否更新?",appStoreVersion] delegate:self cancelButtonTitle:@"跳过"otherButtonTitles:@"更新",nil];
                    [alert show];
                }else{
                    NSLog(@"这个新版本跳过了");
                }
            }else{
                NSLog(@"版本号好像比商店大噢!检测到不需要更新");
            }
            
        });
        
    }];
}
//输出YES(服务器大与本地) 输出NO(服务器小于本地)
- (BOOL)compareEditionNumber:(NSString *)serverNumberStr localNumber:(NSString*)localNumberStr {
    //剔除版本号字符串中的点
    serverNumberStr = [serverNumberStr stringByReplacingOccurrencesOfString:@"." withString:@""];
    localNumberStr = [localNumberStr stringByReplacingOccurrencesOfString:@"." withString:@""];
    //计算版本号位数差
    int placeMistake = (int)(serverNumberStr.length-localNumberStr.length);
    //根据placeMistake的绝对值判断两个版本号是否位数相等
    if (abs(placeMistake) == 0) {
        //位数相等
        return [serverNumberStr integerValue] > [localNumberStr integerValue];
    }else {
        //位数不等
        //multipleMistake差的倍数
        NSInteger multipleMistake = pow(10, abs(placeMistake));
        NSInteger server = [serverNumberStr integerValue];
        NSInteger local = [localNumberStr integerValue];
        if (server > local) {
            return server > local * multipleMistake;
        }else {
            return server * multipleMistake > local;
        }
    }
}
//如果点跳过就记录下跳过的版本号为当前itunes中心查到的版本号
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
    if (buttonIndex==0) {
        [[MethodTool shareTool]setUserDefaults:appStoreVersion :@"appStoreVersion"];
    }else if (buttonIndex==1){
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://itunes.apple.com/cn/app/%E6%99%BA%E6%85%A7%E9%A3%9F%E5%A0%82-h/id1026XXXXXXX1?mt=8"]];
    }
}

7.设置 UIDatePicker的时间选择范围

  datePicker.minimumDate= [NSDate dateWithTimeInterval:-6*24*60*60*300 sinceDate:[NSDate date]];//1800天前的那天
  datePicker.maximumDate= [NSDate date];//今天

设置后 超出范围的滚动会回滚到设定好的时间范围内。

8.生成一个可以供安卓/苹果手机扫描下载安装APP的二维码

芝麻二维码

  • 输入iOS应用的itunes中的下载路径
  • 输入安卓应用的下载路径,可以是百度的安卓市场地址、腾讯的应用宝地址、还可以是自己服务器上的下载地址,注意这个apk文件不可以放在 Root文件下,因为每次打包更新Root文件夹都会被替换,所以需要在Root文件的同层级目录下新建一个文件夹,专门放apk文件,下载地址如下:https://www.xxxxxxx.com/App/xxxxxxx.apk

使用芝麻二维码生成的合并二维码可以加图片,但是使用微信扫描会有中间页面,如果不想要中间页面的话,可以使用 q2r.cc 这个网址来生成合并的二维码,可是不可以添加Logo。

9.如何找到一个APP的itunes下载链接

我们可以通过 Mac上的 itunes 来获取

还可以通过浏览器来获取

在浏览器中 输入 : xxxx on appstore 即可,红色框中的就是手机里面的下载链接。

10.如何实现数据的深拷贝

我们都知道数组中放的都是对象的地址(指针,而不是对象的地址),有这样一个问题,数组A对数组B进行赋值,我们对B数组里面的对象进行操作,但是不希望数组A里面的元素属性发生改变,这样的需求,就需要我们对A数组进行深拷贝,也就是对象拷贝。

如果对数组进行深拷贝?

  _data = [[NSArray alloc]initWithArray:data copyItems:YES];

数组中的对象需要实现NSCopying协议

 <NSCopying>

- (id)copyWithZone:(NSZone *)zone
{
    Nodes *result = [[[self class] allocWithZone:zone] init];
    result.parentId = self.parentId;
    result.nodeId = self.nodeId;
    result.name = self.name;
    result.depth = self.depth;
    result.haveChild = self.haveChild;
    result.expand = self.expand;
    return result;
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 绘图-简单手绘板的实现

    自定义一个UIBezierPath的子类 LGPaintpath,下面是它的初始化方法

    進无尽
  • 绘图- 镂空效果及其动画实现解析

    有时你会看到很多镂空的试图或者是镂空视图的动画效果,感觉很酷炫,其实只要掌握其中实现的原理,想实现怎样的效果就能实现怎样的镂空效果。

    進无尽
  • 编码篇-iOS开发中的奇巧小伎

    最近搜集了自己以前的笔记中的一些小知识点,归为这篇文章,都是亲测有效的奇巧小伎,当你使用到时,你会大呼过瘾的。

    進无尽
  • PyQt5--QCalendar

    py3study
  • 腾讯云cdn回源ip获取

    安全性考虑(假装safe)源站做了访问策略,限制了访问ip,接入cdn后回源的都是cdn节点信息,那么如何获取呢???

    Mr.Du
  • python pyqt5 按钮 QRadioButton 常用

    import sys from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.Qt...

    用户5760343
  • ios开发:关于一对一直播源码中视频录制切换前后摄像头后方向错误解决办法

    最近发现项目里,一对一直播源码切换前后摄像头几次之后,会出现录制的视频方向上下颠倒,可是明明已经在切换一对一直播系统摄像头后,给videoconnection重...

    布谷安妮
  • IOS开发:一对一直播系统中视频录制切换前后摄像头后方向错误解决办法

    最近发现项目里,切换前后摄像头几次之后,会出现录制的视频方向上下颠倒,可是明明已经在切换摄像头后,给videoconnection重新设置了录制方向,我项目视频...

    布谷鸟网络科技
  • 详解文本分类之DeepCNN的理论与实践

    最近在梳理文本分类的各个神经网络算法,特地一个来总结下。下面目录中多通道卷积已经讲过了,下面是链接,没看的可以瞅瞅。我会一个一个的讲解各个算法的理论与实践。目录...

    zenRRan
  • 关于项目里面的硬核漏洞(找不到漏洞看这里)

    以下漏洞过于硬核又比较相对容易挖掘,毕竟我是实习两年半的低危文档工程师。(可能写的不太全)适合在渗透里面没有找到漏洞,以防尴尬。

    Aran

扫码关注云+社区

领取腾讯云代金券