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;
}
网友评论