view 的 frame 操作必须是整体的,ios貌似不允许对结构体的单个变量进行赋值,比如形如:
label.frame.size.height = 20;
这样的操作是不被允许的,但是
label.frame.size = CGSize{20.0,20.0}
却是被允许的,但是对label的frame的改变是不起作用的。要想改变一个view的frame,必须对其整个frame进行修改,只有对整个的frame属性作setter操作,系统才会重新分配位置,否则只改变一部分是不会起作用的。
有时我们在开发时,只用到一个navigationController,但是它控制两个或多个view,通过添加 button 来实现不同的 view 间切换。比如设置 view 的 hidden 属性等。这样实现不同 view 间的切换操作显得很生硬,没有 push 和 pop动画,直接一闪而过。如果想要实现 pop 和 push 动画,可以按以下操作来实现:
sourceView 和 destView 都加载在 self.view 层,实现从 sourceView 到 destView 的切换。首先是 push 切换:
-(void)switchInViewFrom:(UIView *)sourceView toView:(UIView *)destView withCompletionBlock:(void(^)(BOOL finished))block
{
CGRect sourceViewFrame = sourceView.frame;
sourceViewFrame.origin.x = -sourceViewFrame.size.width;
// sourceView.frame = sourceViewFrame;
CGRect destViewFrame = destView.frame;
destViewFrame.origin.x = destView.frame.size.width;
destView.frame = destViewFrame;
destViewFrame.origin.x = 0;
// [sourceView.superview addSubview:destView];
[UIView animateWithDuration:.25 animations:^{
sourceView.frame = sourceViewFrame;
destView.frame = destViewFrame;
} completion:block];
}
以下是pop切换的动画效果:
-(void)switchOutViewFrom:(UIView *)sourceView toView:(UIView *)destView withCompletionBlock:(void(^)(BOOL finished))block
{
CGRect sourceViewFrame = sourceView.frame;
sourceViewFrame.origin.x = sourceViewFrame.size.width;
// sourceView.frame = sourceViewFrame;
CGRect destViewFrame = destView.frame;
destViewFrame.origin.x = -destView.frame.size.width;
destView.frame = destViewFrame;
destViewFrame.origin.x = 0;
// [sourceView.superview addSubview:destView];
[UIView animateWithDuration:.25 animations:^{
sourceView.frame = sourceViewFrame;
destView.frame = destViewFrame;
} completion:block];
}
push 操作将旧的View向左移动,新的View从最右开始进入。pop 操作则是将旧的view右移,新的view从左侧进入。方法也不难,只是先设置好各自即将进入的位置,然后用动画实现即可。block里可以添加完成view切换后的动作。
注意一点,push注释部分sourceView.frame = sourceViewFrame;我之前是加在上面了,然后动画实现,中间过渡的时候会有黑色的块图显示,显得很不友好。这是因为若加上注释的代码,则意味着先将 sourceView 移走,然后再移入 destView,这样在移入新的 view 之前,显示的页面是没有内容的,故而会有黑色块图显示。
另外,之前想着为了解决黑色图块的显示问题,还想着对当前的页面进行截图来填补,代码如下:
//截图处理黑框
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, YES, [UIScreen mainScreen].scale);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIImageView *transView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0, 0.0, self.view.bounds.size.width, self.view.bounds.size.height)];
transView.image = image;
[self.view addSubview:transView];
UIGraphicsEndImageContext();
将上述对 view 的操作换到 viewController 的操作也是一样的。在不使用 navigation 的 push 和 pop 时,可以按以下操作来处理,可以参考:廖雪峰的官方网页 http://www.liaoxuefeng.com/article/0013922124509566432675ba57448dda70659ae1f55906d000点击打开链接
- (void)perform
{
UIViewController* source = (UIViewController *)self.sourceViewController;
UIViewController* destination = (UIViewController *)self.destinationViewController;
CGRect sourceFrame = source.view.frame;
sourceFrame.origin.x = -sourceFrame.size.width;
CGRect destFrame = destination.view.frame;
destFrame.origin.x = destination.view.frame.size.width;
destination.view.frame = destFrame;
destFrame.origin.x = 0;
[source.view.superview addSubview:destination.view];
[UIView animateWithDuration:.25
animations:^{
source.view.frame = sourceFrame;
destination.view.frame = destFrame;
}
completion:^(BOOL finished) {
[source presentViewController:destination animated:NO completion:nil];
}];
}
稍加修改就可以实现从左到右的Push切换动画:
CGRect sourceFrame = source.view.frame;
sourceFrame.origin.x = sourceFrame.size.width;
CGRect destFrame = destination.view.frame;
destFrame.origin.x = -destination.view.frame.size.width;
destination.view.frame = destFrame;
在做步行路线的时候,显示的 label 挡住了指南针的一部分,需要将指南针的位置下移。只需要重写一个方法即可:
// 设置罗盘的高度位置
-(float)getInsetFromTop
{
return GENERALIZE_LABEL_HIGHT + _titleView.frame.size.height;
}
该方法返回罗盘的相对高度,在父类里调用,在子类里重写,调用时覆盖父类的同名方法。
数据库操作时,防止修改失败,每次都添加事物,利用数据回滚技术。不知道具体怎么操作。