我在界面构建器中创建了一个UIView(除了原始视图)。
@interface TimeLineGrid : UIViewController {
UIView *toggleView;
}
@property (nonatomic, retain) IBOutlet UIView *toggleView;
我也合成了它。我已经实现了一个滑动手势,以便在向上滑动时添加切换视图,当向下滑动时,切换视图将被删除。
-(void)swipedUp {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0f];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:NO];
[self.view addSubview:self.toggleView];
[UIView commitAnimations];
}
-(void)swipedDown {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0f];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
[self.toggleView removeFromSuperview];
[UIView commitAnimations];
}
当我向上滑动一次并在此之后向下滑动时,它工作正常。但是当我再次向上滑动时,它会因EXC_BAD_ACCESS错误而崩溃。我知道这与保留计数增加有关,当我添加子视图并减少当我删除子视图时。有人能否对此有所了解?如何实现此切换?
编辑: 我的视图层次结构如下:
->UIView (toggleView)
->UIView (mainView to which toggleView is being added)
-->UIToolBar
答案 0 :(得分:3)
您能否应用此类更改并告知哪些UIView确实存在问题。
启动应用程序后,当您调用它时,您将看到确切处理了哪个对象。
答案 1 :(得分:3)
最有可能的是,当您致电[self.toggleView removeFromSuperview];
时,该视图正在发布。我建议您稍微重新构建一下代码。
由于您在IB中创建视图,因此在头文件中将其声明为
IBOutlet UIView *toggleView;
不包含属性调用或合成。由于您没有设置或获取toggleView,只需通过指针引用它。
在实现中,将指针设置为nil
中的viewDidUnload
并在dealloc
中释放它。然后,按如下方式调整切换方法:
-(void)swipedUp {
if (![toggleView superview]) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0f];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.view cache:NO];
[self.view addSubview:toggleView];
[UIView commitAnimations];
}
}
-(void)swipedDown {
if ([toggleView superview]) {
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0f];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.view cache:NO];
[toggleView removeFromSuperview];
[UIView commitAnimations];
}
}
此处,if
子句将捕获用户连续两次刷新而不响应第二次滑动的事件。另请注意,这会使用toggleView
代替self.toggleView
。
这应解决问题。
答案 2 :(得分:1)
我建议您制作要展示/隐藏的视图,容器视图的子视图。然后,在动画块中首先删除消失的视图并添加要显示的视图。例如:
@interface TimeLineGrid : UIViewController {
// declare the views you want to flip between
UIView *mainView;
UIView *toggleView;
}
@property (nonatomic, retain) IBOutlet UIView *mainView;
@property (nonatomic, retain) IBOutlet UIView *toggleView;
在您的实施中:
// self.view is the container view (an instance of UIView).
// Initially, self.mainView is a subview of self.view
-(void)transitionFromView:(UIView *)fromView toView:(UIView *)toView withAnimation:(UIViewAnimationTransition)animation {
if ([toView superview]) {
// toView already shown
return;
}
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:2.0f];
[UIView setAnimationTransition:animation forView:self.view cache:NO];
[self.view removeFromSuperview:fromView];
[self.view addSubview:toView];
[UIView commitAnimations];
}
-(void)swipedUp {
[self transitionFromView:self.mainView
toView:self.toggleView
withAnimation:UIViewAnimationTransitionFlipFromLeft];
}
-(void)swipedDown {
[self transitionFromView:self.toggleView
toView:self.mainView
withAnimation:UIViewAnimationTransitionFlipFromRight];
}
但请注意,现在不鼓励使用方法setAnimationTransition:forView:cache:
。 Apple建议使用UIView transitionWithView:duration:options:animations:completion:
方法(请参阅UIView reference)。
我希望这有帮助!
答案 3 :(得分:1)
我已经创建了一个包含UITabbar的应用程序,但我使用UIButton获得了相同的行为。
当您不释放调用removeFromSuperview
的对象时会发生这种情况,当我从viewControllers视图中删除UIButton时,我的效果相同。
在我的情况下,我仍然可以看到按钮,如果我点击它,我会得到一个异常,例如无法识别的选择器发送到NSCFString类型的对象。
但是,如果我更改了标签然后返回到我的视图控制器,此按钮在从我的视图中删除后显示在该视图控制器中,然后它就消失了。
所以我的结论是,如果您不释放您正在调用的对象removeFromSuperview
,那么如果您将对象作为类的实例变量并将其添加到视图中,则应用程序将显示一些意外行为以编程方式addSubView
方法。
你有什么选择: -
您可以在uiview或其子类对象上调用removeFromSuperview
并在其上调用release或将其设为nil。
您可以使用hidden
属性隐藏或取消隐藏这些对象,而不是从superview中删除它们。
(我还没有完全尝试过)您可以在类实现中创建一个UIView
对象,然后将其添加为subview
,然后将其分配给您的实例变量使用点运算符,然后释放先前创建的UIView
对象。
我不知道我的答案可能会对你有什么帮助,但我认为与其他人分享你的经验会很好。