绝对定位于tableView,视图层次结构和重绘

时间:2011-04-06 20:53:40

标签: iphone objective-c ios uiview uinavigationcontroller

在我项目的主屏幕上我有一个TableView,顶部有一个navigationBar,底部有一个toolBar。问题是,工具栏中的一个按钮需要从工具栏中向上滑动UISegmentedControl。我已经在自定义UIView中实现了这个控件,但是,如果我只是将它添加到我的rootviewcontroller.view并将其滑动到位,它将滚动表的其余部分,这是不希望的(我希望它显示为工具栏的扩展名。)

那么,我该怎么办?在rootViewController中我做

self.filterView = [[FilterView alloc] initWithTarget:self.tableView reloadDataSelector:@selector(reloadData)];
[[self.view superview] addSubview:self.filterView];
[[self.view superview] bringSubviewToFront:self.filterView];

我将控制视图(self.filterView)添加到我视图的超级视图中,并将其放在tableview的滚动上方。

但是,现在问题。一旦tableView退出视图(我在navigationController上推送另一个视图,或者特别是如果应用程序转到后台),此视图将被重新布局,并且我的控制器视图将移动到(0,0)。

问题是,就在navigationController上推送新视图而言,我可以通过在viewWillAppear中重新定位它并在我的rootViewController中查看viewWillDisappear来控制它。但当应用程序进入后台并返回时,这些功能不会被调用。

那么,有没有办法

(a)阻止我的控制器视图移动

(b)检测何时无意中移动

(c)检测来自rootViewController的后台进出

???

我知道我可以在appDelegate中检测传递到背景,但我觉得处理那里的布局问题感觉不舒服。

谢谢!

修改

添加一些信息,如果我这样做

NSLog(@"%@",[self.view superview]); 

//I get <UIViewControllerWrapperView: 0x61589d0; frame = (0 64; 320 372); autoresize = W+H; layer = <CALayer: 0x615d9c0>>

EDIT2:我想我可以先创建自己的包装器UIView,然后在其中加载我当前的视图层次结构,并将控制器视图放在那里。你觉得那值得吗?是不是有更简单的方法?

EDIT3:结束选择将我的rootViewController从UITableViewController更改为UIViewController,并以编程方式添加tableView,如下面的Phil所示。我现在可以随心所欲地控制我的主视图,因为我将segmentedControl视图放在那里,我可以控制它的位置,而不是之前,当我将它放在UIViewControllerWrapperView中时,我不太确定谁控制或它对它的子视图做了什么。

所以,出于好奇,有没有人知道为什么包装我的UITableViewController视图的UIViewControllerWrapperView正在移动我的UIView从背景中回来?

澄清一下,设置是这样的:

UIViewControllerWrapperView
  |
  |UITableView
  |Custom SegmentedControl UIView

1 个答案:

答案 0 :(得分:3)

作为旁注,您的代码中有一个模式,看起来该视图会泄漏,addSubview会自动将视图放在视图顺序的顶部。

但是,您的视图滚动的原因是因为它被添加为UITableView的子视图,UITableView是UIScrollView的子类。滚动视图滚动时,它将通过contentOffset属性向上或向下移动任何子视图。当UIScrollView滚动时,它将重复布局其子视图。由于表格视图不知道您的自定义子视图,因此它似乎只是将其移动到0,0。

我假设您正在使用UITableViewController。如果您计划为此视图控制器提供多个表视图,则应该实现标准视图控制器。该控制器将具有包含tableview和其他视图的普通视图。 UITableViewController仅仅是为了方便一个非常常见的情况。

如果你担心的话,复制UITableViewController的功能非常容易。它实际上非常清楚地记录在案。

  

即将出现表格视图   第一次加载,   表视图控制器重新加载   表格视图的数据。它也清除了它   选择(有或没有动画,   每次都取决于要求)   将显示表视图。该   UITableViewController类实现   这在超类方法中   viewWillAppear中:.你可以禁用它   通过改变中的值来改变行为   clearsSelectionOnViewWillAppear   属性。

在您的实施中:

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    if ([self.tableView numberOfSections] == 0) {
        [self.tableView reloadData];
    } else {
        [self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:animated];
    }
}
  

当表格视图出现时,   控制器闪烁表视图   滚动指示器。该   UITableViewController类实现   这在超类方法中   viewDidAppear:

在您的实施中:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    [self.tableView flashScrollIndicators];
}
  

它实现了超类方法   setEditing:animated:这样如果是用户   点击中的编辑|完成按钮   导航栏,控制器切换   表格的编辑模式。

在您的实施中:

- (void)setEditing:(BOOL)editing animated:(BOOL)animated {
    [super setEditing:editing animated:animated];
    [self.tableView setEditing:editing animated:animated];
}