ios 以编程方式将 UIPageControl 链接到 UIScrollView

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10198732/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:54:56  来源:igfitidea点击:

Programmatically Linking UIPageControl to UIScrollView

iosxcodeuiscrollviewuipagecontrol

提问by Dan Carew

I am making a simple slideshow view within my app. I'd like to link my UIPageControl to my UIScrollView. This shouldn't be too difficult, but I haven't been able to find a simple solution anywhere. Below is my code.

我正在我的应用程序中制作一个简单的幻灯片视图。我想将我的 UIPageControl 链接到我的 UIScrollView。这应该不会太难,但我一直无法在任何地方找到简单的解决方案。下面是我的代码。

HelpViewController.h

帮助视图控制器.h

#import <UIKit/UIKit.h>

@interface HelpViewController : UIViewController{
}
@end

HelpViewController.m

帮助视图控制器.m

#import "HelpViewController.h"

@interface HelpViewController ()

@end

@implementation HelpViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    CGRect scrollViewFrame = CGRectMake(0, 62, 320, 404);
    UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:scrollViewFrame];
    [self.view addSubview:scrollView];
    CGSize scrollViewContentSize = CGSizeMake(640, 404);
    [scrollView setContentSize:scrollViewContentSize];
    UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(200, 200, 50, 21)];
    [label setText:@"Hello"];
    [scrollView addSubview:label];
    [scrollView setPagingEnabled:YES];
    scrollView.showsHorizontalScrollIndicator = NO;
    UIPageControl *pageControl = [[UIPageControl alloc] init]; 
    pageControl.frame = CGRectMake(110,5,100,100); 
    pageControl.numberOfPages = 2; 
    pageControl.currentPage = 0; 
    [self.view addSubview:pageControl];
    pageControl.backgroundColor = [UIColor redColor];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

@end

回答by Jonas Schnelli

Maybe this works for you

也许这对你有用

Don't forget to set the UIScrollView's delegate = self (or wherever you have the selector below).

不要忘记设置 UIScrollView 的委托 = self(或任何有下面选择器的地方)。

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    CGFloat pageWidth = self.scrollView.frame.size.width; // you need to have a **iVar** with getter for scrollView
    float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
    NSInteger page = lround(fractionalPage);
    self.pageControl.currentPage = page; // you need to have a **iVar** with getter for pageControl
}

For your code it then would be:

对于您的代码,它将是:

.h file

.h 文件

#import <UIKit/UIKit.h>

@interface HelpViewController : UIViewController{
}

@property (nonatomic, retain) UIScrollView *scrollView;
@property (nonatomic, retain) UIPageControl * pageControl;
@end

.m file

.m 文件

#import "HelpViewController.h"

@interface HelpViewController ()

@end

@implementation HelpViewController
@synthesize scrollView=scrollView_;
@synthesize pageControl=pageControl_;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    CGRect scrollViewFrame = CGRectMake(0, 62, 320, 404);
    self.scrollView = [[[UIScrollView alloc] initWithFrame:scrollViewFrame] autorelease];
    self.scrollView.delegate = self;
    [self.view addSubview:self.scrollView];
    CGSize scrollViewContentSize = CGSizeMake(640, 404);
    [self.scrollView setContentSize:scrollViewContentSize];
    UILabel *label  = [[UILabel alloc] initWithFrame:CGRectMake(200, 200, 50, 21)];
    [label setText:@"Hello"];
    [self.scrollView addSubview:label];
    [self.scrollView setPagingEnabled:YES];
    self.scrollView.showsHorizontalScrollIndicator = NO;
    self.pageControl = [[[UIPageControl alloc] init] autorelease]; 
    self.pageControl.frame = CGRectMake(110,5,100,100); 
    self.pageControl.numberOfPages = 2; 
    self.pageControl.currentPage = 0; 
    [self.view addSubview:self.pageControl];
    pageControl.backgroundColor = [UIColor redColor];
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation == UIInterfaceOrientationPortrait);
}

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
        CGFloat pageWidth = self.scrollView.frame.size.width;
        float fractionalPage = self.scrollView.contentOffset.x / pageWidth;
        NSInteger page = lround(fractionalPage);
        self.pageControl.currentPage = page; 
    }


@end

回答by James Andrews

This is actually quite simple to setup. Firstly you need to create the scroll view and page control. Make sure you implement UIScrollViewDelegatein the interface of the class.

这实际上很容易设置。首先,您需要创建滚动视图和页面控件。确保UIScrollViewDelegate在类的接口中实现。

    UIScrollView * scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)];
    scrollView.contentSize = CGSizeMake(scrollView.frame.size.width * 3, scrollView.frame.size.height);
    scrollView.delegate = self;

    UIPageControl * pageControl = [[UIPageControl alloc] initWithFrame:CGRectMake(0, 90, scrollView.frame.size.width, 20)];
    pageControl.numberOfPages = scrollView.contentSize.width/scrollView.frame.size.width;
    [pageControl addTarget:self action:@selector(changePage:) forControlEvents:UIControlEventValueChanged];

Then you need to add the following two methods:

然后需要添加以下两个方法:

- (IBAction)changePage:(id)sender {
    CGFloat x = pageControl.currentPage * scrollView.frame.size.width;
    [scrollView setContentOffset:CGPointMake(x, 0) animated:YES];
}

-(void) scrollViewDidEndDecelerating:(UIScrollView *)scrollView  {
    NSInteger pageNumber = roundf(scrollView.contentOffset.x / (scrollView.frame.size.width));
    pageControl.currentPage = pageNumber;
}

These methods add the required communication between the page control and the scroll view.

这些方法添加了页面控件和滚动视图之间所需的通信。

回答by Bilal

Following code will work for Swift:

以下代码适用于 Swift:

func addScrollView() {        
    let scrollView = UIScrollView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    let numberOfPages: CGFloat = 4
    scrollView.contentSize = CGSize(width: scrollView.frame.width * numberOfPages, height: scrollView.frame.height * numberOfPages)
    scrollView.delegate = self
    scrollView.isPagingEnabled = true

    let pageControl = UIPageControl(frame: CGRect(x: 0, y: scrollView.frame.height - 37, width: scrollView.frame.width, height: 37))
    pageControl.numberOfPages = Int(numberOfPages)
    pageControl.currentPage = 0
}

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    let value = scrollView.contentOffset.x / scrollView.frame.size.width
    pageControl.currentPage = Int(round(value))
}

回答by Harshit K

to get exact page index without rounding off the value simply put the pagecontrol.currentpage in the scrollViewDidEndDecelerating delegate method of scroll view.This works for me!

要在不舍入值的情况下获得准确的页面索引,只需将 pagecontrol.currentpage 放在滚动视图的 scrollViewDidEndDecelerating 委托方法中。这对我有用!

回答by barndog

All these answers are great but I'd like to offer an alternative solution, using ReactiveCocoa!

所有这些答案都很棒,但我想提供一个替代解决方案,使用ReactiveCocoa

The following code makes an assumption that you have a property called scrollViewand one called pageControl.

以下代码假设您有一个名为 的属性scrollView和一个名为的属性pageControl

[RACObserve(self.scrollView, contentOffset)
  subscribeNext:^(NSValue* value){
      CGPoint offset = [value CGPointValue];
      CGFloat fractional = offset.x/self.scrollView.width;
      [self.pageControl setCurrentPage:lroundf(fractional)];
  }];

All that's going on here is you're observing change on the contentOffset property of the scrollView and calculating the page index on every next event (i.e. every time the property value changes).

这里发生的所有事情是您观察 scrollView 的 contentOffset 属性的变化并计算每个下一个事件(即每次属性值更改时)的页面索引。

The only downside of this is that you have to unbox the CGPointbut on the upside there's no UIScrollViewDelegatecode needed at all!

唯一的缺点是您必须将其拆箱,CGPoint但从好的方面来说,根本不需要UIScrollViewDelegate代码!