2013-04-12 25 views
9

使用SDK 6.1,Xcode 4.6.1,我做了一個新的項目主 - 詳細iOS應用程序,ARC,沒有故事板。scrollsToTop不與UIViewController遏制

DetailViewController

然後,在viewDidLoad我添加兩個UITableView中含有的UIViewController s,並確保第二個隱藏這樣的:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    UIViewController *lViewController1 = [[UIViewController alloc] init]; 
    UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame]; 
    lTableView1.scrollsToTop = YES; 
    [lViewController1.view addSubview: lTableView1]; 
    lTableView1.dataSource = self; 
    [self.view addSubview: lViewController1.view]; 
    [self addChildViewController: lViewController1]; 

    UIViewController *lViewController2 = [[UIViewController alloc] init]; 
    UITableView *lTableView2 = [[UITableView alloc] initWithFrame: self.view.frame]; 
    lTableView2.scrollsToTop = YES; 
    [lViewController2.view addSubview: lTableView2]; 
    lTableView2.dataSource = self; 
    [self.view addSubview: lViewController2.view]; 
    [self addChildViewController: lViewController2]; 

    // now hide the view in view controller 2 
    lViewController2.view.hidden = YES; 
} 

(我確保DetailViewController是返回一個數據源100行的UITableViewCell s的所述textLabel.text設置爲@"hello"

第二視圖控制器的存在使得該scrollsToTop(攻絲狀態欄上的)不工作了。如果我不使用UIViewController遏制,只需添加兩個UITableView s並將第二個隱藏,scrollsToTop確實可行。

我在做什麼錯?

+0

下載項目:https://dl.dropboxusercontent.com/u/165243/TestScrollsToTop.zip –

+0

我猜蘋果的代碼不會檢查視圖是否隱藏,當它搜索的視圖有'scrollsToTop'。是否有一個原因,你使用'隱藏'而不是刪除/添加子視圖到超視圖? – fishinear

+0

它確實檢查。如果你不使用視圖控制器遏制它的作品。 –

回答

3

我目前正在試驗您的項目。當

lViewController2.view.hidden = YES; 

被替換

lTableView2.hidden = YES; 

然後滾動的作品,即使控制器遏制。

我試圖在控制器的視圖和表之間插入一個視圖,然後隱藏這個視圖,但表不滾動。

我試圖用shouldAutomaticallyForwardAppearanceMethods進行試驗來隱藏控制器,但表沒有滾動。

結果:在我的實驗中,只有一個滾動視圖必須在視圖層次結構中可見,並且父視圖的hidden屬性未檢出。 hidden必須在所有其他滾動視圖上設置爲NO,而不是其父視圖。

+0

這是我迄今爲止忽視的內容我猜:父視圖的隱藏屬性未檢出。通過使用視圖控制器包容,我在視圖層次結構中添加了一個額外的級別,並更改了父視圖的隱藏屬性,而不是表視圖。我猜蘋果可以更好地記錄這一點(如果它不是bug)。 –

+0

不錯的一個 - 我使用的是「隱藏的滾動視圖,甚至沒有包含它自己的手勢識別器,它只是用來滾動其他內容」技巧,並且因爲隱藏了它而陷入了這個問題。 – Benjohn

7

scrollsToTop只適用於單個可見視圖。從documentation

此手勢適用於單個可見滾動視圖;如果具有此屬性集的多個滾動視圖(例如日期選擇器),或者代表在scrollViewShouldScrollToTop:中返回NO,則UIScrollView將忽略該請求。滾動視圖滾動到內容視圖的頂部後,它會向代理髮送scrollViewDidScrollToTop:消息。

您可以嘗試手動調用[tableView setContentOffset:CGPointZero animated:YES]而不是手動調整每個表(或滾動)視圖。要做到這一點,實現scrollViewShouldScrollToTop:方法在UIScrollViewDelegate協議:

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView { 
    [lTableView1 setContentOffset:CGPointZero animated:YES]; 
    [lTableView2 setContentOffset:CGPointZero animated:YES]; 
    return NO; 
} 
+0

**有**只有一個可見的滾動視圖(請參閱viewDidLoad中代碼的最後一行)。 –

+0

在我的保管箱中放置一個可下載的檔案:https://dl.dropboxusercontent.com/u/165243/TestScrollsToTop.zip –

+0

我認爲你在滾動到頂級事件之前將'hidden'設置爲'NO'。 – Goblin

4

只能設置滾動型每視圖控制器財產.scrollsToTop = YES。 如果設置了2 scrollview.scrollsTopTop = YES,它將停止運行。

ie: your sample project (DetailViewController.m) update following lines, 

line48: lTableView1.scrollsToTop = YES; 
line56: lTableView2.scrollsToTop = NO; 

然後,scrollsToTop工作正常。如果有多個滾動視圖,您希望同時設置「滾動到頂部」,請繼續挖掘。祝你好運!

+0

除非其中一個tableviews被隱藏,否則他們可以將scrollsToTop同時設置爲YES。 **除非您使用視圖控制器遏制**,那麼它不再工作,這就是我正在尋求答案的問題。 –

+0

你可以擁有它setHidden:,removeFromSuperView或setScrollsToTop:不,只要* 1 * scrollView被設置爲響應ScrollsToTop:滾動事件。 – dklt

+0

下載示例代碼,您將看到*不使用視圖控制器遏制*(將DetailViewController中的VIEW_CONTROLLERS定義爲0),使用兩個scrollsToTop表視圖沒有問題。 –

0

經過測試幾個選項和各種命中和嘗試我終於落戶到一個最終的解決方案,即setBounds:scrollView(即tableView在你的情況),它的效果很好。儘管如此,您仍然需要爲動畫付出額外的努力。

CGRect frame = scrollView.frame; 
    frame.origin.x = 0; 
    frame.origin.y = 0; 
    [scrollView setBounds:frame]; 

通過你的情況的方式,試圖返回YES

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView; 

雖然如果沒有定義,假設YES。

+0

不太確定我理解你的答案。您是否建議使用scrollsToTop的自定義實現? –

+0

是的,那只是一擊而已。 – rptwsthi

+0

好的,但在我的項目中,這不是一個選項,也不是這個問題的答案。謝謝:) –

0

我已經使用這個,現在它工作正常。

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
// Do any additional setup after loading the view, typically from a nib. 

    UIViewController *lViewController1 = [[UIViewController alloc] init]; 
    UITableView *lTableView1 = [[UITableView alloc] initWithFrame: self.view.frame]; 
    lTableView1.scrollsToTop = YES; 
    [lViewController1.view addSubview: lTableView1]; 
    lTableView1.dataSource = self; 
    [self.view addSubview: lViewController1.view]; 
    [self addChildViewController: lViewController1]; 
    lTableView1.tag=1; 

    UIViewController *lViewController2 = [[UIViewController alloc] init]; 
    UITableView *lTableView2 = [[UITableView alloc] initWithFrame: self.view.frame]; 
    lTableView2.scrollsToTop = NO; 
    [lViewController2.view addSubview: lTableView2]; 
    lTableView2.dataSource = self; 
    [self.view addSubview: lViewController2.view]; 
    [self addChildViewController: lViewController2]; 
    lTableView2.tag=2; 
    // now hide the view in view controller 2 
    lViewController2.view.hidden = YES; 

} 

- (NSUInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSUInteger)section { 
    return 50; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath  *)indexPath { 
    static NSString * const kCellIdentifier = @"MyCell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:kCellIdentifier]; 
    if (cell == nil) { 
     cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kCellIdentifier]; 
    } 
    cell.textLabel.text = [NSString stringWithFormat:@"hello %d %d",indexPath.row, tableView.tag]; 
    return cell; 
} 
+0

所以你只是改變一個scrolltoToop屬性?這不是我正在尋找的答案(同時,Sulthan的答案已被接受)。 –

+0

@KristofVan這也將工作。 –