2015.5.23
UITableView 的数据源刷新问题
本次发过来的版本五,实现了活动清单列表(AllEventsTableViewController)、活动详情(AllEventsViewController)、今日待办列表(TodayEventTableViewController)
执行时发现:活动清单列表 - 点击+ - 填好标题和细节 - 点击Save
回到清单列表时没有新增的一条活动,直到重新run,才显示数据
在numberOfRowsInSection和cellForRowAtIndexPath加断点,发现点击Save后没有走到这两个方法
原因是:viewWillAppear没有重现加载数据,加上下面操作后
// 刷新Table的数据 [self.tableView reloadData];
今日代办列表也有同样问题
2015.5.24
core data 排序问题
从今日代办切换到活动清单,列表顺序会变化;添加了一个活动后返回活动清单,列表顺序也会变化;
只有重新run一次,才是按顺序;
解决的方法是在viewWillAppear中加入如下代码:
// 按照contents字段排序 NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:@"contents" ascending:YES]; [request setSortDescriptors:[NSArray arrayWithObject:sort]];
其实更好的处理办法是,增加一个任务添加时间eventAddTime属性,按照这个属性排序;
2015.5.24
点击今日代办列表的一栏,跳转到当下清单页,发现显示的一直是第一例
排查发现,是获取indexPath的方法有问题
// 旧的 TodayEventTableViewCell* cell=(TodayEventTableViewCell*)[sender superview]; // 新的 TodayEventTableViewCell* cell=(TodayEventTableViewCell*)sender;
上面这行代码是从网上copy的,是点击cell的一个button时,用的代码;
但是目前是点击整个区域调转,此时
2015.6.1
错误:Incompatible integer to pointer conversion assigning to 'NSUInteger *' (aka 'unsigned long *') from 'int'
原因:定义非负整形时,应该用 NSUInteger,而不是 NSUInteger *
问题:从tableView点击某个cell,跳到cell的页面,如何使底部的tabbar隐藏?
方法:
toDoVC.hidesBottomBarWhenPushed = YES;
[self.navigationController pushViewController:toDoVC animated:NO];
2015.6.6
问:如何修改tabbar上各tabbaritem的文字和图标
答:
如果是代码实现
tabBarItem = [[UITabBarItem alloc] initWithTitle:title image:image selectedImage:selectedImage];
如果是storyboard
选中storyboard中的tabbaritem,然后在Attribute Inspecter里修改title和image
问:如何设置夜景模式
答:网上查到的夜间模式,比较复杂,需要准备两套图片素材
我这边打算先实现简单的,用一个UISwitch控制,夜间模式降背景颜色设置为灰色
对于设置页,可以直接用目标-动作(target-action)来实现
但是如果同时改变其他页面的背景颜色,则需要用通知-委托(notification-delegate)实现
另外,夜间模式也可以通过调节亮度实现:
UIScreen *mainScreen = [UIScreen mainScreen]; if (switchButton.on) { self.view.backgroundColor = [UIColor grayColor]; mainScreen.brightness = 0; } else { self.view.backgroundColor = [UIColor whiteColor]; mainScreen.brightness = 0.5; }
2015.6.7
为了实现水纹效果,从网上找了个demo:RippleTableViewController
原来的cell是用storyboard实现的,转移按钮是直接拖过去的
现在要用代码实现转移按钮,所以需要自定义 AllEventsTableViewCell
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; UIButton *transButton = [[UIButton alloc] initWithFrame:CGRectMake(300, 15, 50, 20)]; [transButton setTitle:@"转移" forState:UIControlStateNormal]; [transButton setBackgroundColor:[UIColor blueColor]]; [self.contentView addSubview:transButton]; [transButton addTarget:self action:@selector(transAction:) forControlEvents:UIControlEventTouchUpInside]; self.button = transButton; return self; } - (IBAction)transAction:(id)sender { if (self.actionBlock) { self.actionBlock(); } }
几点说明下:
1、添加button的操作,放在UITableViewCell的指定初始化方法中;
2、transButton要添加到cell的contentView属性中,对应的
AllEventsTableViewCell *cell =(AllEventsTableViewCell*)[sender.superview superview];
sender就是button,sender.superview就是contentView,[sender.superview superview]就是cell;
3、forControlEvents:UIControlEventTouchUpInside
注意event要选对,一开始没注意,选了UIControlEventAllTouchEvents,导致每次点击会触发两次action(每次touch,会有手指点下和抬起两次event)
4、要想cell里面button的点击向ViewController传递消息,需要用到block
__weak AllEventsTableViewCell *weakCell = cell; cell.actionBlock = ^{ AllEventsTableViewCell *strongCell = weakCell; [self eventMoveToTodayEvents:strongCell.button]; };
这里涉及到block、retain cycle、weak、strong等概念,暂时还不是太清楚,看下斯坦福第8集视频;
换一种写法也可以:
// cell初始化时,加上__block __block AllEventsTableViewCell *cell = [[AllEventsTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"AllEventsTableViewCell"]; // 其他对cell的操作 // ... cell.actionBlock = ^{ [self eventMoveToTodayEvents:cell.button]; cell = nil; };
注意:加上__block后,变量在块中保存的不在是变量的值,而是变量的地址,所以可以被修改;
斯坦福第8集介绍__block讲到,如果加上这个修饰,此变量会从栈移到堆中,从而可以在block中使用,等block结束,再将信息复制回堆,再放回到栈上;
栈 - 复制到堆 - block中改变其值 - 将值复制到堆 - 再放回到栈
每次向block中的对象发送消息时,系统都会创建一个指向该对象的强指针,直至block不存在
这里要加上 cell = nil,否则会提示可能引入retain cycle
http://www.cnblogs.com/tangbinblog/archive/2012/12/31/2840690.html
这篇博客讲得还不错