3GShare的仿写
登陆注册页面
这个界面的UI比较简单,比较困难的地方在于限制我们的输入长度以及我们输入的字符类型。
在这里我是通过在textField的代理中设计限定输入字符的内容,从而实现限制输入长度和限制输入字符的内容,下面给出相关的代码。
-(BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
NSCharacterSet *charSet = [[NSCharacterSet characterSetWithCharactersInString:@"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"] invertedSet];
NSString *filteredStr = [[string componentsSeparatedByCharactersInSet:charSet] componentsJoinedByString:@""];
if (range.length == 1 && string.length == 0) { // 这一个判断是为防止他出现一个到达限定字数后,删除键失效的一个问题
return YES;
} else if (textField.text.length >= 15) { //。限定长度
textField.text = [textField.text substringToIndex:15]; // 截取对应长度
return NO;
} else if ([string isEqualToString:filteredStr] && textField.text.length <= 15) {
return YES;
}
return NO;
}
这里我为了判断是否存在重复注册的问题,我通过两次传值来给不同界面传入登陆和注册的一个字典,先通过属性传值将数组内容传入注册界面,再通过协议传值的方法将后一个页面注册的字典传回登陆页面,这样就可以实现一个登陆注册的效果。
首页
首页这部分比较重要的内容是有关于点赞传值的部分,我们要保证在传值前后我的点赞可以在两个页面中间实现一个传值的效果,这里我是采用了一个全局变量,在通过判断这个全局变量来判断点赞的一个状态,注意将全局变量定义在这个AppDelegate,因为这样可以被我们全部的文件访问。
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (nonatomic, assign) BOOL selected;
@end
- (void)press1:(UIButton *)btn {
btn.selected = !btn.selected;
AppDelegate* mydelegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
mydelegate.selected = btn.selected;
}
其次就是无限轮播图在我们滑动UITableView的时候仍然需要滑动,所以我们需要添加一条代码来修改这个部分的内容。
[[NSRunLoop currentRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];
笔者对于RunLoop还没有进行一个较为深的学习,仅仅只是知道这个段代码可以起到让UIScrollView在UiTableView被滑动的时候不停止滑动的效果。
这个页面主要就是一个自定义cell和一个滑动视图两者构成。
搜索页面
这个页面主要由UIButton构成,上面使用了一个UISearchBar这个控件,这个页面比较简单,就不在赘述。
上传页面
这里是一个上传页面,我设计的是永远显示的上传后点击的第一张,这里主要和前面照片墙的方式一样,同样是给UIButton添加两个状态,如果点击后就会给右下角添加一个对勾,表明他被选中的一个状态。这里主要是通过一个可变数组添加和删除来保存返回照片的第一张图片。
同时这个页面还有一个折叠cell,折叠cell主要是通过一个可变数组和一个UItableView来实现这部分内容。下面给出相关代码:
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString* str = _ary[indexPath.section];
[_ary removeObjectAtIndex:indexPath.section];//删除这个位置的字符串
[_ary insertObject:str atIndex:0];//插入在首位
[tableView reloadData]; //记得刷新单元格
[self press:_btn]; //显示所有内容
}
-(UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"id"];
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
cell.textLabel.text = self.ary[indexPath.section];
return cell;
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
return 30;
}
-(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 4;
}
-(void)press:(UIButton*)btn {
btn.selected = !btn.selected;
if (btn.selected) {
self.tableView.frame = CGRectMake(240, 180, 120, 120);
} else {
self.tableView.frame = CGRectMake(240, 180, 120, 30);
}
}
文章页面
这个页面比较简单就是单纯的一个分栏控件再加上UIScrollView的一个嵌套,以及UIScrollView中嵌套着一个UITableView的控件的组成。
活动页面
这个页面就是简单的一个自定义cell的内容。
个人主页
下面就是一个个人主页的部分,这个部分内容比较多写起来比较麻烦,这个部分的重点还主要是如何保存我们被pop的视图控制器。
if (!self.personal) {
self.personal = [[personalCenterViewController alloc] init];
}
[self.navigationController pushViewController:self.personal animated:YES];
}
这段代码可以让我的视图控制器只创建一次,从而防止他被反复创建从而不能保存原来持有状态的问题,剩下其实都是有关自定义cell的内容。
小tips
在这个项目中还学习了一些UITableView设计的一些技巧,下面将给出相关代码。
- 首先我们可以通过给设置空白VIew的方式来给我们的UITableView设置组间距。
-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
if(section == 0) {
return 0.001;
} else {
return 12;
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
return 12;
}
-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
UIView *headerView;
if (section == 0) {
headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 0.001)];
} else {
headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, 12)];
}
return headerView;
}
- 可以通过给tabBar添加一个VIew来遮盖底部白条。
UIView* view = [[UIView alloc] initWithFrame:CGRectMake(0, 50, WIDTH, 50)];
view.backgroundColor = [UIColor colorWithRed:23 / 255.0f green:23 / 255.0f blue:23 / 255.0f alpha:1];
[self.tabBarController.tabBar addSubview:view];
- 自定义导航栏返回按钮
UIButton* leftButton = [UIButton buttonWithType:UIButtonTypeSystem];
[leftButton setImage:[UIImage imageNamed:@"back_img.png"] forState:UIControlStateNormal];
[leftButton addTarget:self action:@selector(returnback) forControlEvents:UIControlEventTouchUpInside];
[leftButton setTitle:@"返回" forState:UIControlStateNormal];
leftButton.tintColor = UIColor.whiteColor;
UIBarButtonItem* left = [[UIBarButtonItem alloc] initWithCustomView:leftButton];
self.navigationItem.leftBarButtonItem = left;
- 通过用一个UILabel来作为titleView的方式来设置我们导航栏中间字体的样式
UILabel* titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 40, 40)];
titleLabel.font = [UIFont systemFontOfSize:26];
titleLabel.textColor = [UIColor whiteColor];
titleLabel.text = @"SHARE";
_tagFirst = 110;
_tagSecond = 130;
self.navigationItem.titleView = titleLabel;
总结
通过这次3GShare的仿写主要让我了解有关协议传值和属性传值的相关用法,以及简单了解了有关通过UITableView来实现一个简单的聊天室的效果。