前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >实践-小细节Ⅵ

实践-小细节Ⅵ

作者头像
進无尽
发布2018-09-12 18:13:59
9200
发布2018-09-12 18:13:59
举报
文章被收录于专栏:進无尽的文章進无尽的文章

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

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

解决办法: _Tb.backgroundColor=litteGray;

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

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

效果图

代码语言:javascript
复制
    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的字体颜色和大小 有两种方法,不过要注意的是要写在最后面,之前就是因为写在最前面被覆盖导致无效果的。

代码语言:javascript
复制
第一种  
    [[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. 对于这样复杂页面的绘制心得

代码语言:javascript
复制
    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的位置,其他的控件位置就定了,这样最简单

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

代码语言:javascript
复制
 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的底部视图

代码语言:javascript
复制
[AddNewImageAndVideoV updateLayout];
[self.sc setContentSize:CGSizeMake(WIDTH, AddNewImageAndVideoV.origin.y+AddNewImageAndVideoV.frame.size.height)];

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

使用UIView动画实现:

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

使用SDK的动画效果实现:

代码语言:javascript
复制
 [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 加上

代码语言:javascript
复制
- (NSString *)description {    
        return [NSString stringWithFormat:@"%@",[self mj_keyValues]];
}
- (NSString *)debugDescription {   
        return   [NSString stringWithFormat:@"%@ -- %p",[self mj_keyValues], self];
}

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

1504837404190908.jpg

6. 版本的检测更新提示

代码语言:javascript
复制
-(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的时间选择范围

代码语言:javascript
复制
  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数组进行深拷贝,也就是对象拷贝。

如果对数组进行深拷贝?

代码语言:javascript
复制
  _data = [[NSArray alloc]initWithArray:data copyItems:YES];

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

代码语言:javascript
复制
 <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;
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017.10.17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. UITableView的空白区域颜色设置
  • 2. 关于UISearchBar 的设置以及取消按钮的颜色和文字设置
  • 3. 对于这样复杂页面的绘制心得
  • 4. 动态添加高度很高的Cell
  • 5. 实现description方法 打印出Model属性
  • 6. 版本的检测更新提示
  • 7.设置 UIDatePicker的时间选择范围
    • 8.生成一个可以供安卓/苹果手机扫描下载安装APP的二维码
    • 9.如何找到一个APP的itunes下载链接
    • 10.如何实现数据的深拷贝
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档