ios - UITableView内部的UIRefreshControl导致应用程序卡住旋转-iOS 6+

标签 ios uiviewcontroller uirefreshcontrol

好的,StackOverflow的人...我有一个很有趣的问题,我一直在努力解决数日,无法解决,因此我需要一些重要的帮助。这很可能是一个非常冗长的描述,但是请您多多包涵,并在此先深深地感谢您阅读所有这些内容,因为我的用词越多,我就越能清楚地向大家描述整个情况。我将竭尽所能,做到尽可能简洁和连贯。请让我知道我哪里不足。

这是我问题的上下文:我在iOS应用程序和应用程序中的特定导航选项卡上使用情节提要,我必须为纵向和横向创建两个单独的场景。这样做的原因(而不是使用Autolayout)是因为在该选项卡中,根据方向的不同,视觉元素(表格视图,Web视图等)的布局也有所不同,这要容易得多创建一个单独的定位场景来处理UI中的此更改,而不是通过编程方式来完成-(这也更容易理解和更清晰地执行代码)。因此,需要记住的所有事情是,这两个单独的“纵向”和“横向”场景代表了我的应用程序中的“相同”选项卡。 (旁注:这些场景当然是在IB中制作的)

现在,我在前面的UI中提到的可视元素-更深入地介绍,它们都是不同UIViewControllers的容器。我将应用程序中的所有内容沙盒化,并且几乎所有内容都具有一对一的关系,因此这些容器将映射到我为特定目的而创建的子类UIViewControllers,但这是我的问题的第一个警告出现。这是一个更清晰图片的实际示例,我有一个UIViewController,其中包含一个称为UITableViewMXSAnnouncementsViewController,并且在Landscape和Portrait场景中都存在相同的视图控制器。我没有为该视图控制器创建显式的Portrait或Landscape VERSION,而是让该控制器跟踪指向特定于方向的IBOutlet的两个tableViewLandscape属性(tableViewPortraitUITableViews),并且这种方法可以很好地工作。此外,在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 action:@selector(refreshTableView:) forControlEvents:UIControlEventValueChanged];
    [self.tableView addSubview:refreshControl];
}

因为我已经在前面解释了旋转操作的整个视图生命周期顺序,所以总而言之,如果我在setupPullToRefresh末尾为viewDidLoad注释掉最后一条MXSAnnouncementsViewController指令,则我的应用程序可以正常工作。如果我包含该指令,则我的应用程序在第一次旋转时将变得完全无响应,并且我一生都无法找出原因。不知道我在这里处理的是什么情况。欢迎任何见解,并非常感谢您阅读所有这些内容!

最佳答案

最好的方法可能是放弃当前的设计,即使用两个单独的纵向和横向控制器。在iOS上,您应始终按所需方向重播视图,而不要破坏和重新创建所有内容。通过尝试通过重新创建所有内容来处理它,我只会遇到麻烦。

如果您知道的话,可以使用自动布局在旋转时对视图进行复杂的重新排序,但最好的选择是取消当前代码以进行横向显示,并编写代码以在旋转时自行重新排列视图。您所遇到的问题将大大减少,您的代码也将更易于他人理解和维护。

当您删除一小段代码时,您的应用程序似乎可以正常运行,但是幕后可能发生了一些不太正确的事情,将来可能会再次引起您的注意。这可能就是为什么添加代码行会破坏它。

关于ios - UITableView内部的UIRefreshControl导致应用程序卡住旋转-iOS 6+,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20889203/

相关文章:

ios - Swift 3.0 Xcode8 beta 4 如何修复 Calendar.current.date

ios - 添加额外控件时的 UITableViewController 或 UIViewController

ios - 如何在 iOS 上的 View 之间切换

ios - 带有 UIRefreshControl 的 TableView 在重新加载时似乎有点故障?

ios - 3 秒后 UIRefreshControl endRefreshing

ios - 快速在特定数组元素中添加值

ios - 尝试在右上角格式化图像 – SwiftUI

iOS使视频背景模糊

swift - 如何以编程方式调整模态视图的大小 (SWIFT)

swift - ScrollView UIRefreshControl 未调用函数