当通过手势识别器滑动切换到仅点击选项卡时,在 tabbarcontroller 中切换选项卡会给出不同的结果

Posted

技术标签:

【中文标题】当通过手势识别器滑动切换到仅点击选项卡时,在 tabbarcontroller 中切换选项卡会给出不同的结果【英文标题】:Switching tabs in tabbarcontroller giving different results when switching by gesturerecognizer swipe to just tapping tab 【发布时间】:2014-03-25 22:08:30 【问题描述】:

我有一个带有 2 个选项卡的选项卡控制器。我已经设置了一个滑动手势识别器,允许用户在标签之间滑动,用户也可以点击一个标签来转到那个标签。

在第二个选项卡的视图控制器中,我在主视图中有一个子视图。我使用平移手势识别器设置了子视图,允许用户通过 2 根手指拖动来移动子视图。默认子视图位置是视图的右下角(来自情节提要)。如果用户将子视图拖动到不同的位置,我将子视图的中心点保存在 viewwilldisappear 如果用户滑动到第一个选项卡或只是点击选项卡栏上的第一个选项卡。当用户返回到第二个选项卡(通过从第一个选项卡视图滑动或通过点击选项卡栏上的第二个选项卡)时,我将子视图的中心设置为 viewWillAppear 中保存的中心点属性。

奇怪的是,如果我手动从右下角(比如左上角)移动子视图位置,则在标签更改时会发生以下情况

    如果我通过点击 tabbar 从 tab2 转到 tab 1,然后通过向左滑动返回 tab2 - 子视图保持在正确的“移动”位置,即右上角

    但是如果我通过向右滑动从 tab2 转到 tab 1,然后通过向左滑动返回 tab2 - 子视图首先出现在默认的右下角位置,然后消失并立即重新出现在正确的位置(“移动”)位置,即左上角

    最后,如果我通过任一方法转到选项卡 1,然后通过点击选项卡栏返回选项卡 2,则子视图仅显示在默认的右下角位置(不反映先前的移动)。我检查了并且 tab2 viewcontroller 中 viewWillAppear 中的代码行似乎正在运行,但在我看来,好像其他一些与标签栏相关的代码可能会在之后运行以将子视图放回默认位置

关于正在发生的事情以及如何让子视图保持新位置的任何想法?以及如何停止子视图暂时出现在上面第 2 点中描述的默认位置。任何帮助表示赞赏

这是我滑动到其他标签的代码

- (IBAction)nextTab:(id)sender 

NSInteger fromIndex = [self.tabBarController selectedIndex];
NSInteger toIndex = fromIndex + 1;

if (toIndex > self.tabBarController.viewControllers.count - 1) 
    return;
 else 

    //transition code
    UIView *fromView = self.tabBarController.selectedViewController.view;//create the from view
    UIView *toView = [[self.tabBarController.viewControllers objectAtIndex:toIndex] view];//create the to view

    // Get the size of the view area.
    CGRect viewSize = fromView.frame;
    BOOL scrollRight = toIndex > fromIndex;

    // Add the to view to the tab bar view.
    [fromView.superview addSubview:toView];

    // Position it off screen.
    UIInterfaceOrientation orientation = self.interfaceOrientation;
    if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) 
        toView.frame = CGRectMake((scrollRight ? 768 : -768), viewSize.origin.y, 768, viewSize.size.height);
     else 
        toView.frame = CGRectMake((scrollRight ? 1024 : -1024), viewSize.origin.y, 1024, viewSize.size.height);
    

    [UIView animateWithDuration:0.3
                     animations: ^

                         // Animate the views on and off the screen. This will appear to slide.
                         if (orientation == UIInterfaceOrientationPortrait || orientation == UIInterfaceOrientationPortraitUpsideDown) 
                             fromView.frame =CGRectMake((scrollRight ? -768 : 768), viewSize.origin.y, 768, viewSize.size.height);
                             toView.frame =CGRectMake(0, viewSize.origin.y, 768, viewSize.size.height);
                          else 
                             fromView.frame =CGRectMake((scrollRight ? -1024 : 1024), viewSize.origin.y, 1024, viewSize.size.height);
                             toView.frame =CGRectMake(0, viewSize.origin.y, 1024, viewSize.size.height);
                         

// fromView.frame =CGRectMake((scrollRight ? -768 : 768), viewSize.origin.y, 768, viewSize.size.height); // toView.frame =CGRectMake(0, viewSize.origin.y, 768, viewSize.size.height);

                     completion:^(BOOL finished) 
                         if (finished) 
                             // Remove the old view from the tabbar view.
                             [fromView removeFromSuperview];
                             self.tabBarController.selectedIndex = toIndex;
                         
                     ];

这是我在第二个标签中的 viewwillappear 代码

-(void)viewWillAppear:(BOOL)animated

[super viewWillAppear:animated];//call to super ow super will run its own code only?


//show the clock and then use ns timer to keep it updating
[self updateClock:nil];
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(updateClock:) userInfo:nil repeats:YES];

//position the clock in custom spot if repositioned
self.clockView.center = self.clockViewCentre;
NSLog(@"x= %f",self.clockView.center.x);

【问题讨论】:

【参考方案1】:

viewWillAppear 在布局完成之前被调用。所以改变clockView中心的代码应该在viewDidLayoutSubviews

【讨论】:

是的,谢谢你似乎已经完美地修复了它。有没有一种快速简便的方法可以让我查看诸如视图、tabbarcontrollers、视图控制器等方法调用顺序的列表。或者这只是阅读苹果指南和经验的问题。 主要是苹果指南和经验。我将NSLog( @"%s", __func__ ) 放入所有视图控制器的 viewWill... 和 viewDid... 方法中,看看顺序是什么:)

以上是关于当通过手势识别器滑动切换到仅点击选项卡时,在 tabbarcontroller 中切换选项卡会给出不同的结果的主要内容,如果未能解决你的问题,请参考以下文章

android 手势操作中滑动和滚动的区别

在选项卡式视图应用程序中滑动手势

在 UIWebView 中向后/向前滑动手势?

改变滑动手势识别器的过渡

手势识别器不适用于选项卡式应用程序

滑动手势识别器在垂直方向上不起作用