如何将视图添加到 UIScrollView 并使其与 UIPageControl 保持同步?

发布于 2024-12-31 21:27:20 字数 163 浏览 0 评论 0原文

我需要在我的应用程序中动态创建一些视图,并再次动态地在它们上面放置一些按钮。如果按钮的数量(计数)超过 10 个,我想将按钮放置在新视图上,并且视图之间的转换必须使用 UIPageControl。尽管我在苹果的开发者页面上进行了谷歌搜索和搜索,但我找不到解决问题的方法。有人可以帮忙吗?

I need to dynamically create some views in my app and place some buttons on them dynamically again. If the amount (count) of the buttons is more then ten I want to place the buttons on a new view and the transitions between the views must be with UIPageControl. Even though I googled and searched from Apple's Developer page I couldn't find a way of solving my problem. Can someone please help?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

七秒鱼° 2025-01-07 21:27:20

使用 addSubview 方法将视图添加为 UIScrollView 的并排子视图。然后将 UIPageControl 与 UIScrollView 结合使用,如这个 示例


我创建了一个类来管理 UIScrollView、UIPageControl 和 UIView 数组。这是我在自己的代码中使用的简化版本。它执行以下操作:

  • 设置滚动视图以显示 UIView 数组。它不关心视图是否是动态生成的。
  • 处理滚动和页面控制事件。
  • 将滚动视图与页面控件同步。

PageViewManager.h

#import <Foundation/Foundation.h>

@interface PageViewManager : NSObject <UIScrollViewDelegate>
{
    UIScrollView* scrollView_;
    UIPageControl* pageControl_;
    NSArray* pages_;
    BOOL pageControlUsed_;
    NSInteger pageIndex_;
}

- (id)initWithScrollView:(UIScrollView*)scrollView
             pageControl:(UIPageControl*)pageControl;
- (void)loadPages:(NSArray*)pages;
- (void)loadControllerViews:(NSArray*)pageControllers;

@end

PageViewManager.m

#import "PageViewManager.h"

@interface PageViewManager ()

- (void)pageControlChanged;

@end

@implementation PageViewManager

- (id)initWithScrollView:(UIScrollView*)scrollView
             pageControl:(UIPageControl*)pageControl
{
    self = [super init];
    if (self)
    {
        scrollView_ = scrollView;
        pageControl_ = pageControl;
        pageControlUsed_ = NO;
        pageIndex_ = 0;

        [pageControl_ addTarget:self action:@selector(pageControlChanged)
               forControlEvents:UIControlEventValueChanged];
    }
    return self;
}

/*  Setup the PageViewManager with an array of UIViews. */
- (void)loadPages:(NSArray*)pages
{
    pages_ = pages;
    scrollView_.delegate = self;
    pageControl_.numberOfPages = [pages count];

    CGFloat pageWidth  = scrollView_.frame.size.width;
    CGFloat pageHeight = scrollView_.frame.size.height;

    scrollView_.pagingEnabled = YES;
    scrollView_.contentSize = CGSizeMake(pageWidth*[pages_ count], pageHeight);
    scrollView_.scrollsToTop = NO;
    scrollView_.delaysContentTouches = NO;

    [pages_ enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop)
    {
        UIView* page = obj;
        page.frame = CGRectMake(pageWidth * index, 0,
                                pageWidth, pageHeight);
        [scrollView_ addSubview:page];
    }];
}

/*  Setup the PageViewManager with an array of UIViewControllers. */
- (void)loadControllerViews:(NSArray*)pageControllers
{
    NSMutableArray* pages = [NSMutableArray arrayWithCapacity:
                             pageControllers.count];
    [pageControllers enumerateObjectsUsingBlock:
        ^(id obj, NSUInteger idx, BOOL *stop)
        {
            UIViewController* controller = obj;
            [pages addObject:controller.view];
        }];

    [self loadPages:pages];
}

- (void)pageControlChanged
{
    pageIndex_ = pageControl_.currentPage;

    // Set the boolean used when scrolls originate from the page control.
    pageControlUsed_ = YES;

    // Update the scroll view to the appropriate page
    CGFloat pageWidth  = scrollView_.frame.size.width;
    CGFloat pageHeight = scrollView_.frame.size.height;
    CGRect rect = CGRectMake(pageWidth * pageIndex_, 0, pageWidth, pageHeight);
    [scrollView_ scrollRectToVisible:rect animated:YES];
}

- (void)scrollViewDidScroll:(UIScrollView*)sender
{
    // If the scroll was initiated from the page control, do nothing.
    if (!pageControlUsed_)
    {
        /*  Switch the page control when more than 50% of the previous/next
            page is visible. */
        CGFloat pageWidth = scrollView_.frame.size.width;
        CGFloat xOffset = scrollView_.contentOffset.x;
        int index = floor((xOffset - pageWidth/2) / pageWidth) + 1;
        if (index != pageIndex_)
        {
            pageIndex_ = index;
            pageControl_.currentPage = index;
        }
    }
}

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

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

@end

要使用此类,请将其嵌入到包含 UIScrollView 和 UIPageControl 的 UIViewController 中。

用法:

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

    // Create some views dynamically
    UIView* v1 = ...
    UIView* v2 = ...

    // Put the views inside an NSArray:
    NSArray* pages_ = [NSArray arrayWithObjects:v1, v2, nil];

    /* Create the PageViewManager, which is a member (or property) of this
       UIViewController. The UIScrollView and UIPageControl belong to this 
       UIViewController, but we're letting the PageViewManager manage them for us. */
    pageViewManager_ = [[PageViewManager alloc]
                        initWithScrollView:self.scrollView
                               pageControl:self.pageControl];

    // Make the PageViewManager display our array of UIViews on the UIScrollView.
    [pageViewManager_ loadViews:pages_];
}

我的示例代码假设您正在使用 ARC。

Add your views as side-by-side subviews of an UIScrollView, using the addSubview method. Then use the UIPageControl with the UIScrollView, as in this example.


I made a class that manages a UIScrollView, a UIPageControl, and an array of UIViews. It is a simplified version of what I use in my own code. It does the following:

  • Sets up the scroll view to display an array of UIViews. It doesn't care if the views have been generated dynamically or not.
  • Handles scroll and page control events.
  • Synchronizes the scroll view with the page control.

PageViewManager.h

#import <Foundation/Foundation.h>

@interface PageViewManager : NSObject <UIScrollViewDelegate>
{
    UIScrollView* scrollView_;
    UIPageControl* pageControl_;
    NSArray* pages_;
    BOOL pageControlUsed_;
    NSInteger pageIndex_;
}

- (id)initWithScrollView:(UIScrollView*)scrollView
             pageControl:(UIPageControl*)pageControl;
- (void)loadPages:(NSArray*)pages;
- (void)loadControllerViews:(NSArray*)pageControllers;

@end

PageViewManager.m

#import "PageViewManager.h"

@interface PageViewManager ()

- (void)pageControlChanged;

@end

@implementation PageViewManager

- (id)initWithScrollView:(UIScrollView*)scrollView
             pageControl:(UIPageControl*)pageControl
{
    self = [super init];
    if (self)
    {
        scrollView_ = scrollView;
        pageControl_ = pageControl;
        pageControlUsed_ = NO;
        pageIndex_ = 0;

        [pageControl_ addTarget:self action:@selector(pageControlChanged)
               forControlEvents:UIControlEventValueChanged];
    }
    return self;
}

/*  Setup the PageViewManager with an array of UIViews. */
- (void)loadPages:(NSArray*)pages
{
    pages_ = pages;
    scrollView_.delegate = self;
    pageControl_.numberOfPages = [pages count];

    CGFloat pageWidth  = scrollView_.frame.size.width;
    CGFloat pageHeight = scrollView_.frame.size.height;

    scrollView_.pagingEnabled = YES;
    scrollView_.contentSize = CGSizeMake(pageWidth*[pages_ count], pageHeight);
    scrollView_.scrollsToTop = NO;
    scrollView_.delaysContentTouches = NO;

    [pages_ enumerateObjectsUsingBlock:^(id obj, NSUInteger index, BOOL *stop)
    {
        UIView* page = obj;
        page.frame = CGRectMake(pageWidth * index, 0,
                                pageWidth, pageHeight);
        [scrollView_ addSubview:page];
    }];
}

/*  Setup the PageViewManager with an array of UIViewControllers. */
- (void)loadControllerViews:(NSArray*)pageControllers
{
    NSMutableArray* pages = [NSMutableArray arrayWithCapacity:
                             pageControllers.count];
    [pageControllers enumerateObjectsUsingBlock:
        ^(id obj, NSUInteger idx, BOOL *stop)
        {
            UIViewController* controller = obj;
            [pages addObject:controller.view];
        }];

    [self loadPages:pages];
}

- (void)pageControlChanged
{
    pageIndex_ = pageControl_.currentPage;

    // Set the boolean used when scrolls originate from the page control.
    pageControlUsed_ = YES;

    // Update the scroll view to the appropriate page
    CGFloat pageWidth  = scrollView_.frame.size.width;
    CGFloat pageHeight = scrollView_.frame.size.height;
    CGRect rect = CGRectMake(pageWidth * pageIndex_, 0, pageWidth, pageHeight);
    [scrollView_ scrollRectToVisible:rect animated:YES];
}

- (void)scrollViewDidScroll:(UIScrollView*)sender
{
    // If the scroll was initiated from the page control, do nothing.
    if (!pageControlUsed_)
    {
        /*  Switch the page control when more than 50% of the previous/next
            page is visible. */
        CGFloat pageWidth = scrollView_.frame.size.width;
        CGFloat xOffset = scrollView_.contentOffset.x;
        int index = floor((xOffset - pageWidth/2) / pageWidth) + 1;
        if (index != pageIndex_)
        {
            pageIndex_ = index;
            pageControl_.currentPage = index;
        }
    }
}

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

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

@end

To use this class, you embed it inside a UIViewController than contains the UIScrollView and the UIPageControl.

Usage:

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

    // Create some views dynamically
    UIView* v1 = ...
    UIView* v2 = ...

    // Put the views inside an NSArray:
    NSArray* pages_ = [NSArray arrayWithObjects:v1, v2, nil];

    /* Create the PageViewManager, which is a member (or property) of this
       UIViewController. The UIScrollView and UIPageControl belong to this 
       UIViewController, but we're letting the PageViewManager manage them for us. */
    pageViewManager_ = [[PageViewManager alloc]
                        initWithScrollView:self.scrollView
                               pageControl:self.pageControl];

    // Make the PageViewManager display our array of UIViews on the UIScrollView.
    [pageViewManager_ loadViews:pages_];
}

My sample code assumes that you're using ARC.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文