禁用通过子视图中包含的IBAction滚动

时间:2011-11-01 19:00:15

标签: xcode uiview delegates uiscrollview ibaction

我的iPad应用程序目前是这样构建的:xml数据从我的网站中提取并在View Controller“FishIDView”中解析。这个视图控制器有一个UIScrollView“scrollView”,它有一个子视图“XMLView”,它是一个UIView。 scrollView的设置使它可以根据XML中包含的项目数滚动和浏览XMLViews。例如,12个项目= 12个页面,或XMLView实例。这些页面包含单个鱼的照片。这些页面中的每一个都包含一个按钮,用于创建名为“flipView”的UIView“XMLView”的子视图,并通过左侧动画过渡的翻转显示子视图。该子视图包含有关图片鱼的信息。 flipView有一个按钮,可以将用户(翻转)返回到鱼图片。

我的问题是,当我查看flipView(它是XMLView的子视图,它是scrollView的子视图)时,仍然启用滚动。如果我在flipView上向左或向右滚动,我会看到下一条鱼的XMLView。我希望在查看flipView时禁用滚动。

我可以做些什么来从子视图发送类似setScrollEnabled:NO命令到scrollView(在FishIDView上)?

修改

所以我假设我需要使用协议和委托。我以为我可以搞清楚,但我已经开始了解实施。

在我的XMLView.h中(遗漏了无关的代码):

@protocol XMLViewDelegate <NSObject>

- (void) stopScrolling;

@end

@interface XMLView : UIView 
{
    ...
    id                      secondDelegate;
}
...
@property (nonatomic, retain) id <XMLViewDelegate>    secondDelegate;
...

@end

然后在我的XMLView.m中(将IBAction挂钩到可正常工作的UIButton):

...
@synthesize secondDelegate;
...
-(IBAction)goToInfo
{
    //[self newPage];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];
    [self.secondDelegate stopScrolling];
    [self addSubview:flipView];
    ...

    NSLog(@"button pressed");

}

在FishIDView.h中:

@interface FishIDView : UIViewController <XMLViewDelegate>

FishIDView.m:

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

    [scrollView setScrollEnabled:YES];

    XMLView *subsubView = [[XMLView alloc] init];
    subsubView.secondDelegate = self;
    ...
}

-(void) stopScrolling
{
    [scrollView setScrollEnabled:NO];
    NSLog(@"NO more scrolling!!!");
}

当我点击XMLView中触发“goToInfo”的按钮时,其余动作发生,但日志“不再滚动!!”从不显示。

我是以错误的方式解决这个问题的吗?我仍然在试图找出代表,所以我对这种方法可能完全错了。

编辑2:

我现在已经尝试摆脱委托并转向听起来更简单的路线,但它仍然无法正常工作。

在XMLView.m中:

-(IBAction)goToInfo
{
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:1.0];
    [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self cache:YES];

    //The next 2 lines are what I added
    ViewController *mainView = [[ViewController alloc] init];
    [mainView stopScrolling];

    [self addSubview:flipView];
    [infoButton setEnabled:FALSE];
    [infoButton setHidden:YES];
    [title setHidden:YES];
    [UIView commitAnimations];

    NSLog(@"button pressed");

}

然后在FishIDView.h

-(void) stopScrolling;

FishIDView.m

-(void) stopScrolling
{
    [scrollView setScrollEnabled:NO];
    NSLog(@"NO more scrolling!!!");
}

“不再滚动!!!”打印,但scrollView仍然启用滚动!为什么它会运行stopScrolling的NSLog部分而不是setScrollEnabled:NO?谁能帮我?

1 个答案:

答案 0 :(得分:2)

解决!我合并了Notifications而不是尝试直接从子视图中调用方法。

我的设置快速概述。 UIViewController FishIDView包含一个名为scrollView的UIScrollView。 scrollView有一个子视图XMLView。 XMLView有一个按钮,显示其子视图flipView。当flipView可见时,我想在scrollView上禁用滚动。

在XMLView.h中(省略了不相关的代码):

#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>

#define kApplicationDidStopScrollingNotification @"StopScroll"
#define kApplicationDidResumeScrollingNotification @"ResumeScroll"

#import "FishIDView.h"

@interface XMLView : UIView 
{
    IBOutlet UIButton       *infoButton;
    IBOutlet UIButton       *closeButton;
    IBOutlet UIView         *flipView; 
}

@property (nonatomic, retain) IBOutlet UIButton       *infoButton;
@property (nonatomic, retain) IBOutlet UIButton       *closeButton;

- (IBAction)goToInfo;

- (IBAction)closeSubView;

@end

在XMLView.m中:

#import "XMLView.h"

@implementation XMLView

@synthesize infoButton, closeButton;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

//Allows button to be pressed while contained in subview of scrollview
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    CGPoint hitPoint = [infoButton convertPoint:point fromView:self];
    CGPoint closePoint = [closeButton convertPoint:point fromView:flipView];
    if ([infoButton pointInside:hitPoint withEvent:event]) return infoButton;
    if ([closeButton pointInside:closePoint withEvent:event]) return closeButton;
    return [super hitTest:point withEvent:event];  
}

-(IBAction)goToInfo
{
    //post notification for FishIDView to listen to to trigger method that disables scrolling
    [[NSNotificationCenter defaultCenter] postNotificationName:kApplicationDidStopScrollingNotification object:nil];

    [self addSubview:flipView];

    //custom transition between views. A cross-fade effect
    flipView.alpha = 0.0f;
    [UIView beginAnimations:@"fadeInSecondView" context:NULL];
    [UIView setAnimationDuration:0.5];
    flipView.alpha = 1.0f;

    [infoButton setEnabled:FALSE];

    [UIView commitAnimations];   
}

- (IBAction)closeSubView
{
    //post notification to resume scrolling
    [[NSNotificationCenter defaultCenter] postNotificationName:kApplicationDidResumeScrollingNotification object:nil];

    flipView.alpha = 1.0f;
    [UIView beginAnimations:@"fadeInSecondView" context:NULL];
    [UIView setAnimationDuration:0.5];
    flipView.alpha = 0.0f;

    [infoButton setEnabled:TRUE];

    [UIView commitAnimations];
    [flipView performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:1.2];

}

@end

确保将#import“XMLView.h”放在顶部的FishIDView.h文件中,并在底部创建 - (void)方法。

#import <UIKit/UIKit.h>

#import "XMLView.h"

@class AppDelegate;

@interface FishIDView : UIViewController <UIScrollViewDelegate>
{
...
}

@property ...

//These are the 2 methods that turn scrolling on and off
-(void) stopScrolling;
-(void) resumeScrolling;

@end

然后在FishIDView.m

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

    //Listen for the notification to stop scrolling
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(stopScrolling) name:kApplicationDidStopScrollingNotification object:nil];

    //Listen for the notification to resume scrolling
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(resumeScrolling) name:kApplicationDidResumeScrollingNotification object:nil];
    [self layoutSubview];
}

-(void) stopScrolling
{    
    [scrollView setScrollEnabled:NO];
    NSLog(@"NO more scrolling!!!");
}

-(void) resumeScrolling
{    
    [scrollView setScrollEnabled:YES];
    NSLog(@"begin scrolling again!!");
}

如果有人有疑问或在实施此问题时遇到问题,我将很乐意分享更多代码。我只是省略了大部分内容,因为它并不真正属于这个主题。