iOS iPad 应用程序:未调用具有两个 UIScrollViews 和一个 UIPageControl 的 ViewController 的委托(未调用分页的委托函数)
Posted
技术标签:
【中文标题】iOS iPad 应用程序:未调用具有两个 UIScrollViews 和一个 UIPageControl 的 ViewController 的委托(未调用分页的委托函数)【英文标题】:iOS iPad App: Delegates not called for ViewController with two UIScrollViews and a UIPageControl (delegate functions for paging NOT CALLED) 【发布时间】:2013-01-09 21:46:49 【问题描述】:对于我的 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;
视图出现了,但是当我在按钮上滑动时,我没有看到上面的委托函数被调用。
我没有在 *** 中找到解决此问题的方法,尽管我已经考虑了其他相关帖子的其他方面的建议(例如区分哪个滚动视图已启动操作的逻辑等)
在此处添加详细代码(应@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;
【问题讨论】:
第一个明显的问题要问 - 你有没有在你的滚动视图上设置代表?是在代码中还是在 Interface Builder 中连接? 是的,我已经在 Interface Builder 中设置了所有三个。所以 mainScrollView、thumbScrollView 和 pageControl 在 IB 中连接到 VC 的 .h 文件中的上述声明。 这是为 ios 5.1 iPad 模拟器编码/运行的。 我还编写了一个 changePage 函数,我将它设置为 PageControl 的 'touchupinside' IBAction。当我在 pagecontrol 上手动选择一个点时会调用它,但是无论我在 thumbScrollView 上执行什么操作,委托函数 scrollViewDidScroll 等都不会被调用。 @HeWas - 请参阅我的 cmets 来回答您的问题(感谢您对此的帮助) 【参考方案1】:你的代码看起来都是 100%(除了这个错字:@synthesize floorplanThumbScrollView;
,但这不是你的问题)。
我确信答案是您没有在 IB 中正确连接您的滚动视图 DELEGATES。
这是线索:
“是的,我已经在 Interface Builder 中设置了所有三个。所以 mainScrollView、thumbScrollView 和 pageControl 在 IB 中连接到 VC 的 .h 文件中的上述声明。”
您的 ViewController 和您的滚动视图之间需要 2 个连接。
(1) ctrl-drag FROM viewController to scrollView,连接到 IBOutlet 属性。 这就是你所做的。
(2) ctrl-drag FROM scrollView 到 viewController,连接到delegate
。
我认为你没有这样做。
第二步说明
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的委托协议声明的所有必需方法,并且可以选择实现任何可选 em> 委托方法。 Here is the protocol
要确定需要哪些方法,请阅读UIScrollView class reference,它告诉您:
UIScrollView 类可以有一个必须采用 UIScrollViewDelegate 协议的委托。要使缩放和平移工作,代理必须同时实现
viewForZoomingInScrollView:
和scrollViewDidEndZooming:withView:atScale:
;此外,最大 (maximumZoomScale
) 和最小 (minimumZoomScale
) 缩放比例必须不同。
协议中的所有其他内容都是可选的。
这种委托模式是一种您可以轻松实现自己以重用自己的对象的委托模式,并且是在 Objective-C 中解耦对象之间传递消息的最常见方式之一。
【讨论】:
太完美了!我就是这样做的,效果很好!非常感谢! :-) 现在看到它工作的兴奋,我不想失去这个学习机会!你能回顾一下那个缺失的步骤(即第 2 步)做了什么吗?它确实解决了这个问题,但我没有注意到 ImageBrowseViewController.h 代码中有任何变化。此步骤(步骤 2)背后的基本原理是什么? @CoolDocMan,查看扩展答案 啊哈我现在明白了!是的,正如您所说,我错过的步骤是... [myScrollView setDelegate:self] 感谢您提供如此清晰的解释并教育我这些工作方式以及提供方便的替代方案 - 使用 IB 设置滚动视图的委托!以上是关于iOS iPad 应用程序:未调用具有两个 UIScrollViews 和一个 UIPageControl 的 ViewController 的委托(未调用分页的委托函数)的主要内容,如果未能解决你的问题,请参考以下文章
ios将ipad应用程序转换为通用显示此错误笔尖但未设置视图出口
Xamarin.iOS SKProductRequest 事件未在 Debug 中调用(在 iOS 15 和 xCode 13 之前工作)