アプリ内で簡単なスライドショービューを作成しています。 UIPageControlをUIScrollViewにリンクしたいと思います。これはそれほど難しくないはずですが、どこでも簡単な解決策を見つけることができませんでした。以下は私のコードです。
HelpViewController.h
#import <UIKit/UIKit.h>
@interface HelpViewController : UIViewController{
}
@end
HelpViewController.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
たぶんこれはあなたのために働く
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
}
コードの場合、次のようになります。
.hファイル
#import <UIKit/UIKit.h>
@interface HelpViewController : UIViewController{
}
@property (nonatomic, retain) UIScrollView *scrollView;
@property (nonatomic, retain) UIPageControl * pageControl;
@end
.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
これは実際にはセットアップが非常に簡単です。まず、スクロールビューとページコントロールを作成する必要があります。クラスのインターフェースに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];
次に、次の2つのメソッドを追加する必要があります。
- (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;
}
これらのメソッドは、ページコントロールとスクロールビューの間に必要な通信を追加します。
次のコードは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))
}
値を四捨五入せずに正確なページインデックスを取得するには、スクロールビューのscrollViewDidEndDeceleratingデリゲートメソッドにpagecontrol.currentpageを配置するだけです。
これらの答えはすべて素晴らしいですが、 ReactiveCocoa !を使用して、代替ソリューションを提供したいと思います。
次のコードは、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)];
}];
ここで行われているのは、scrollViewのcontentOffsetプロパティの変更を観察し、次のすべてのイベント(つまり、プロパティ値が変更されるたび)でページインデックスを計算することです。
これの唯一の欠点は、CGPoint
のボックスを解除する必要があることですが、欠点はUIScrollViewDelegate
コードがまったく必要ないことです!