好的,StackOverflow的人...我有一个很有趣的问题,我一直在努力解决数日,无法解决,因此我需要一些重要的帮助。这很可能是一个非常冗长的描述,但是请您多多包涵,并在此先深深地感谢您阅读所有这些内容,因为我的用词越多,我就越能清楚地向大家描述整个情况。我将竭尽所能,做到尽可能简洁和连贯。请让我知道我哪里不足。
这是我问题的上下文:我在iOS应用程序和应用程序中的特定导航选项卡上使用情节提要,我必须为纵向和横向创建两个单独的场景。这样做的原因(而不是使用Autolayout)是因为在该选项卡中,根据方向的不同,视觉元素(表格视图,Web视图等)的布局也有所不同,这要容易得多创建一个单独的定位场景来处理UI中的此更改,而不是通过编程方式来完成-(这也更容易理解和更清晰地执行代码)。因此,需要记住的所有事情是,这两个单独的“纵向”和“横向”场景代表了我的应用程序中的“相同”选项卡。 (旁注:这些场景当然是在IB中制作的)
现在,我在前面的UI中提到的可视元素-更深入地介绍,它们都是不同UIViewControllers 的容器。我将应用程序中的所有内容沙盒化,并且几乎所有内容都具有一对一的关系,因此这些容器将映射到我为特定目的而创建的子类UIViewControllers ,但这是我的问题的第一个警告出现。这是一个更清晰图片的实际示例,我有一个UIViewController ,其中包含一个称为UITableView 的MXSAnnouncementsViewController ,并且在Landscape和Portrait场景中都存在相同的视图控制器。我没有为该视图控制器创建显式的Portrait或Landscape VERSION,而是让该控制器跟踪指向特定于方向的IBOutlet 的两个tableViewLandscape 属性(tableViewPortrait 和UITableViews ),并且这种方法可以很好地工作。此外,在MXSAnnouncementsViewController 中,我有一个名为tableView 的本地属性,该属性抽象了特定于方向的表视图。它在viewDidLoad 中设置,您可以在下面看到:
- (void)viewDidLoad
{
[super viewDidLoad];
if (self.tableViewPortrait) {
self.tableView = self.tableViewPortrait;
} else {
self.tableView = self.tableViewLandscape;
}
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
if (![MXSAnnouncementManager sharedAnnouncementManager].latestAnnouncements) {
[MXSAnnouncementManager loadModel"MXSAnnouncementGroupAllAnnouncements" withBlock:^(id model, NSError *error) {
if (!error) {
self.arrayLatestAnnouncements = [MXSAnnouncementManager sharedAnnouncementManager].latestAnnouncements;
[self.tableView reloadData];
} else {
// show some error msg
}
}];
} else {
self.arrayLatestAnnouncements = [MXSAnnouncementManager sharedAnnouncementManager].latestAnnouncements;
}
[self setupPullToRefresh];
}
每当我在选项卡中时,两个特定于方向的IBOutlets 之一始终处于 Activity 状态,并且在内存中具有地址,而另一个是nil 。每当我轮换使用时,角色都会反转-以前在内存中具有地址的任何内容现在都为nil ,而另一个已初始化并分配了,这就是为什么我要使用上面代码段中的tableView 属性进行操作的原因。这是警告#2出现在其中的地方,这是个麻烦事-它与视图生命周期有关。为了清楚起见,这是一个实际的示例:说我以横向放置应用程序。当我这样做时,我的tableViewLandscape 出口在内存中有一个地址,而我的tableViewPortrait 出口是nil 。这是预期的行为。现在,当我旋转应用程序时,疯狂的事情开始了。在这个地方,我需要所有人了解UIViewControllers 实例以及正常与非正常情况,因此请缓慢而仔细地阅读以下内容。
立即旋转应用程序将导致相反方向的场景(MXSAnnouncementsViewController 的另一个INSTANCE ???)调用其viewDidLoad 方法(在此示例中,我们在Landscape中,因此Portrait场景将调用该方法)。在该方法中,将我的本地tableView 属性设置为该方向的当前 Activity 表格视图(请参见上面的代码段)。该方法完成后,先前的MXSAnnouncementsViewController LANDSCAPE实例将调用其viewWillDisappear 方法,然后调用PORTRAIT实例对其viewWillAppear 方法进行调用,然后最后以LANDSCAPE实例调用其willRotateToInterfaceOrientation 回调作为结束-这就是我的操作顺序我从断点看到。我真的希望您能得到所有这些,因为我的想法刚刚从这一切中消失了。
如果此时您仍然与我在一起,谢谢,因为我们终于可以在家了。就像这篇文章的标题所暗示的那样,我要解决的问题是我的应用程序冻结了旋转。如果您没有注意到viewDidLoad 片段,则最后一条要执行的指令是setupPullToRefresh 方法,如下所示:
- (void)setupPullToRefresh
{
UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init];
[refreshControl addTarget:self actionselector(refreshTableView forControlEvents:UIControlEventValueChanged];
[self.tableView addSubview:refreshControl];
}
因为我已经在前面解释了旋转操作的整个视图生命周期顺序,所以总而言之,如果我在setupPullToRefresh 末尾为viewDidLoad 注释掉最后一条MXSAnnouncementsViewController 指令,则我的应用程序可以正常工作。如果我包含该指令,则我的应用程序在第一次旋转时将变得完全无响应,并且我一生都无法找出原因。不知道我在这里处理的是什么情况。欢迎任何见解,并非常感谢您阅读所有这些内容!
Best Answer-推荐答案 strong>
最好的方法可能是放弃当前的设计,即使用两个单独的纵向和横向控制器。在iOS上,您应始终按所需方向重播视图,而不要破坏和重新创建所有内容。通过尝试通过重新创建所有内容来处理它,我只会遇到麻烦。
如果您知道的话,可以使用自动布局在旋转时对视图进行复杂的重新排序,但最好的选择是取消当前代码以进行横向显示,并编写代码以在旋转时自行重新排列视图。您所遇到的问题将大大减少,您的代码也将更易于他人理解和维护。
当您删除一小段代码时,您的应用程序似乎可以正常运行,但是幕后可能发生了一些不太正确的事情,将来可能会再次引起您的注意。这可能就是为什么添加代码行会破坏它。
关于ios - UITableView内部的UIRefreshControl导致应用程序卡住旋转-iOS 6+,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/20889203/
|