0

对于我的 iPad 应用程序,我有一个主 ViewController,其中包含两个 UIScrollview 和一个 UIPageControl。问题是寻呼的代表没有被调用。这是布局:

在此处输入图像描述

在底部 thumbScrollView 中选择一个按钮需要更新 mainScrollView 中的图像(这可行) 滑动 thumbScrollView 或在 pageControl 上选择一个点需要“分页” thumbScrollView 以显示下一组按钮。刷卡不起作用,因为委托函数没有被调用。

我在我的 VC 中声明滚动视图和页面控件如下

@property (strong, nonatomic) IBOutlet UIScrollView *mainScrollView;
@property (strong, nonatomic) IBOutlet UIScrollView *thumbScrollView;
@property (strong, nonatomic) IBOutlet UIPageControl *pageControl;

ViewController 实现 UIScrollViewDelegate

@interface MyViewController : UIViewController<UIScrollViewDelegate>

我在我的 VC 的 .m 文件中实现了以下 UIScrollViewDelegate 委托函数。

- (void)scrollViewDidScroll:(UIScrollView *)sender;
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView;
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView;

视图出现了,但是当我在按钮上滑动时,我没有看到上面的委托函数被调用。

我没有在 StackOverflow 中找到解决方案,尽管我已经考虑了其他相关帖子的其他方面的建议(例如,区分哪个滚动视图已启动操作的逻辑等)

在此处添加详细代码(根据@HeWas 的要求)

这是控制两个滚动视图和页面控件的主视图控制器的头文件(相关摘录 - 如果您需要更多信息,请告诉我)

// ImageBrowseViewController.h
// (NOTE - In Interface Builder I have added a tag attribute of 0 to mainScrollView
//  and 1 to thumbScrollView, to enable me to distinguish which scrollView the delegate 
//  needs to respond to)



#define TAG_MAIN_SCROLLVIEW 0
#define TAG_THUMB_SCROLLVIEW 1

@interface ImageBrowseViewController : UIViewController<UIScrollViewDelegate>
{
    UIButton* currentlySelectedButton;
    UIScrollView *mainScrollView;
    UIScrollView *thumbScrollView;
    UIPageControl* pageControl;
    BOOL pageControlBeingUsed;

}

@property (strong, nonatomic) IBOutlet UIScrollView *mainScrollView;
    // … connected as outlet in IB to mainScrollView
@property (strong, nonatomic) IBOutlet UIScrollView * thumbScrollView;
    // … connected as outlet in IB to thumbScrollView
@property (strong, nonatomic) IBOutlet UIPageControl *pageControl;
    // … connected as outlet in IB to pageControl


…
-(IBAction)changePage; //Touch up Inside IBAction connected to pageControl


…
@end

这是控制两个滚动视图和页面控件的主视图控制器的实现文件(相关摘录 - 如果您需要更多信息,请告诉我)

//
//  ImageBrowseViewController.m
//

    …
@synthesize mainScrollView;
@synthesize thumbScrollView;
@synthesize pageControl;


// UIScrollViewDelegate
- (void)scrollViewDidScroll:(UIScrollView *)sender {

    if ( [sender tag] == TAG_THUMB_SCROLLVIEW ) {
        // This is the thumbScrollview
        // Update the page when more than 50% of the previous/next page is visible

        CGFloat pageWidth = self.thumbScrollView.frame.size.width;
        int page = 
            floor((self.thumbScrollView.contentOffset.x - pageWidth / 2) / pageWidth) 
            + 1;
        self.pageControl.currentPage = page;

    }
}
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
    pageControlBeingUsed = NO;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    pageControlBeingUsed = NO;
}

- (IBAction)changePage {
    // Update the scroll view to the appropriate page
    CGRect frame;
    //frame.origin.x = self.scrollView.frame.size.width * self.pageControl.currentPage;
    frame.origin.x = self.thumbScrollView.frame.size.width * self.pageControl.currentPage;

    frame.origin.y = 0;
    frame.size = self.thumbScrollView.frame.size;
    [self.thumbScrollView scrollRectToVisible:frame animated:YES];

    // Keep track of when scrolls happen in response to the page control
    // value changing. If we don't do this, a noticeable "flashing" occurs
    // as the the scroll delegate will temporarily switch back the page
    // number.
    pageControlBeingUsed = YES;
}
4

1 回答 1

1

您的代码看起来都是 100%(除了这个错字:@synthesize floorplanThumbScrollView;,但这不是您的问题)。

我确信答案是您没有在 IB 中正确连接您的滚动视图DELEGATES

这是线索:

“是的,我在 Interface Builder 中设置了所有三个。所以 mainScrollView、thumbScrollView 和 pageControl 在 IB 中连接到 VC 的 .h 文件中的上述声明。”

您需要在 ViewController 和 scrollViews 之间建立 2 个连接。

(1) ctrl-drag FROM viewController TO scrollView,连接到 IBOutlet 属性。
这就是你所做的。

(2) ctrl-drag FROM scrollView TO viewController,连接到delegate.
我不认为你已经这样做了。

步骤 2 的说明

UIScrollView 有一个名为“delegate”的内置属性。scrollView 使用此属性向其委托发送消息。您可以在界面生成器中设置此委托(步骤 2),也可以在代码中进行。例如,在您的 viewController 中,您可以这样做:

    [myScrollView setDelegate:self];

这会将 viewController 设置为 myScrollView 的委托。如果您通过在 Interface Builder 中链接来执行此操作,则不需要此代码(并且 IB 不会创建任何代码)。

无论哪种方式,这实际上都是将 scrollView 的委托 iVar 设置为指向 viewController 的指针。像这样使用委托的好处是委托人 (UIScrollView) 不必知道任何关于委托人的事情(在这种情况下是您的 UIViewController)。只要我们遵守它的委托协议,这允许我们重用 UIScrollView。

每当 scrollView 需要通知它的委托时,它会在内部发送这样的消息..

    [self.delegate scrollViewDidScroll:self];

(你看不到,它在scrollView的实现中)。

您设置为 scrollView 委托的对象需要实现 scrollView 的委托协议声明的所有必需方法,并且可以选择实现任何可选委托方法。 这是协议

要确定需要哪些方法,请阅读UIScrollView 类参考,它告诉您:

UIScrollView 类可以有一个必须采用 UIScrollViewDelegate 协议的委托。要使缩放和平移工作,代理必须同时实现viewForZoomingInScrollView:and scrollViewDidEndZooming:withView:atScale:; 此外,最大 ( maximumZoomScale) 和最小 ( minimumZoomScale) 缩放比例必须不同。

协议中的其他所有内容都是可选的。

这种委托模式是您可以轻松实现自己以重用自己的对象的一种模式,并且是在 Objective-C 中解耦对象之间传递消息的最常见方式之一。

于 2013-01-10T17:55:11.070 回答