写真アプリのようなギャップとページUIScrollViewとpagingEnabled
-
21-08-2019 - |
質問
UIScrollViewにページングモードでは、ページ内にある、ない。ただし、写真を開くの写真アプリとスワイプを通して、写真ている事がわかるでしょうにはギャップにページをめくる事が可能です。またこれらの差です。
いため、既存ソリューションする場合があり、奇想を約の実施のページの隙間も私が最も気に入っていて説明します。それとも、私はあの子も明らかなやん欠?
明らかにするものと:たいのギャップだけに見えながらスクロール、なめ込みのページです。
私のプランは左右にずらしてみてくださいページのコンテンツ内 scrollViewDidScroll
コールバック、その前提とはないスクロール右の当初の目標ページを若干オフセット右のページの境界の時間に到着するまでは、対象のページですので、その適切な位置の情報は、こちらをご覧くは若干オフセットの左にある。(かく移動も継続的に、僕もよく移動するオフセットかう途中にページをめくる事が可能です。)
私の著書であるの ScrollingMadness第+例 そしていつもこちらを参照にしてください。私の実施progammaticズームレンズにもかかわらず-写真のズーム+スクロールとインター写真のページ欄に入力してください。その奏法を学ばなければならなかとUIScrollView、宿に最先端のもの。
ないでくださいものでTTScrollView.しかし、私が多くの人ですが、自分のものと考えるので感じるからネイティブUIScrollView行動と利用しないでっす。
解決
この答えはかなり古いであることに注意してください。基本的なコンセプトはまだなく、動作します あなたはハードあなたが無視した場合でもiOS7および8にビューのサイズを符号化するべきではありません そのアドバイスは、あなたが480または330を使用しないでください。
あなたはあなたのイメージのフルスクリーンを表示することを想定し、同じわずか-大より-画面境界にあなたのサブビューを配置する(画面よりもUIScrollView
のフレームがわずかに大きくなったことがあります。
#define kViewFrameWidth 330; // i.e. more than 320
CGRect scrollFrame;
scrollFrame.origin.x = 0;
scrollFrame.origin.y = 0;
scrollFrame.size.width = kViewFrameWidth;
scrollFrame.size.height = 480;
UIScrollView* myScrollView = [[UIScrollView alloc] initWithFrame:scrollFrame];
myScrollView.bounces = YES;
myScrollView.pagingEnabled = YES;
myScrollView.backgroundColor = [UIColor redColor];
UIImage* leftImage = [UIImage imageNamed:@"ScrollTestImageL.png"];
UIImageView* leftView = [[UIImageView alloc] initWithImage:leftImage];
leftView.backgroundColor = [UIColor whiteColor];
leftView.frame = CGRectMake(0,0,320,480);
UIImage* rightImage = [UIImage imageNamed:@"ScrollTestImageR.png"];
UIImageView* rightView = [[UIImageView alloc] initWithImage:rightImage];
rightView.backgroundColor = [UIColor blackColor];
rightView.frame = CGRectMake(kViewFrameWidth * 2,0,320,480);
UIImage* centerImage = [UIImage imageNamed:@"ScrollTestImageC.png"];
UIImageView* centerView = [[UIImageView alloc] initWithImage:centerImage];
centerView.backgroundColor = [UIColor grayColor];
centerView.frame = CGRectMake(kViewFrameWidth,0,320,480);
[myScrollView addSubview:leftView];
[myScrollView addSubview:rightView];
[myScrollView addSubview:centerView];
[myScrollView setContentSize:CGSizeMake(kViewFrameWidth * 3, 480)];
[myScrollView setContentOffset:CGPointMake(kViewFrameWidth, 0)];
[leftView release];
[rightView release];
[centerView release];
謝罪これはコンパイルできない場合、私は戻って肖像画にそれを編集した風景のアプリと手でそれをテストしました。私はあなたががアイデアを得ると確信しています。これは、全画面表示のために常にそうなりますスーパークリッピングに依存しています。
他のヒント
だから私は上記の答えにコメントを投稿するための十分な「担当者」を持っていません。その答えは正しいのですが、注意すべき大きな問題があります:
あなたはUINavigationControllerの一部だのViewControllerでUIScrollViewのを使用している場合は、ナビゲーションコントローラは、あなたのscrollViewのフレームのサイズを変更されます。
それはあなたが別のビューを切り替えるためにUINavigationControllerを使用してアプリを持っている、です。あなたはscrollViewを持っているのViewControllerを押すと、あなたはViewControllerをの-init方法でこのscrollViewを作成します。あなたが(0、0、340、480)のフレームに割り当てる。
さて、あなたが作成したscrollViewのフレームを取得し、あなたのViewControllerの-viewDidAppear方法に進みます。あなたは、幅が320個のピクセルに縮小されたことがわかります。そのため、ページングが正常に動作しません。あなたはscrollViewが340個のピクセルを移動するために期待するだろうが、それは、代わりに、320を移動します。
UINavigationControllerは、サブビューをいじりのビット悪名高いです。これは、それらを移動し、ナビゲーションバーに対応するために、それらのサイズを変更します。要するに、それはチームプレーヤーではありません - 特にこのケースで。ウェブ上の他の場所では、あなたの意見のサイズと場所を正確に制御する必要がある場合は、UINavigationControllerを使用しないことを示唆しています。彼らは、代わりに、あなたはUINavigationBarをもとに、独自のnavigationControllerクラスを作成することをお勧めします。
まあ、それは仕事のトンです。幸いにも、簡単に解決策があります:あなたのViewControllerの-viewDidAppear方法でscrollViewの枠を設定します。この時点で、UINavigationControllerは、フレームをいじり行われているので、あなたはそれがあるべきとscrollViewが正常に動作します何にそれをリセットすることができます。
これは、OS 3.0に関連しています。私は、3.1または2.2.1をテストしていません。私はまた、我々は、そのクラスがサブビューオフその汚い手を保つことができますように、彼らは、このような「-shouldAutoarrangeSubviews」としてBOOLでUINavigationControllerを変更することを示唆しているAppleとバグレポートを提出してきました。
それは一緒に来るまで、上記の修正はUINavigationController内のページ分割UIScrollViewの中にあなたのギャップを与えるだろう。
アップルは、iPhoneデベロッパプログラムのすべてのメンバーに2010 WWDCセッションビデオをリリースしました。議論のトピックの1つは、写真アプリを作成する方法です!彼らは一歩非常によく似たアプリのステップを構築し、自由のためのすべてのコードが利用可能になっています。
これは、どちらかのプライベートAPIを使用していません。ここではサンプルコードのダウンロードへのリンクです。おそらく、アクセス権を取得するにはログインする必要があります。
そして、ここではiTunesのWWDCのページへのリンクがあります:
<のhref = "http://insideapple.apple.com/redir/cbx-cgi.do?v=2&la=en&lc=&a=kGSol9sgPHP%2BtlWtLp%2BEP%2FnxnZarjWJglPBZRHd3oDbACudP51JNGS8KlsFgxZto9X%2BTsnqSbeUSWX0doe%2Fzv%2FN5XV55%2FomsyfRgFBysOnIVggO% 2Fn2p%2BiweDK%2F%2FmsIXj」REL = "noreferrer"> http://insideapple.apple.com/redir/cbx-cgi.do?v=2&la=en&lc=&a=kGSol9sgPHP%2BtlWtLp%2BEP%2FnxnZarjWJglPBZRHd3oDbACudP51JNGS8KlsFgxZto9X%2BTsnqSbeUSWX0doe% 2Fzv%2FN5XV55%2FomsyfRgFBysOnIVggO%2Fn2p%2BiweDK%2F%2FmsIXj の
これを行う方法は、いくつかの組み合わせです。
あなたの画像間の20ピクセルのギャップをしたい場合は、は、以下を行う必要があります:
まず、20ピクセルで、あなたのスクロールビューの合計幅を拡大し、10pxので左に動かします。
あなたがあなたのイメージのXLOCをレイアウトするとき、彼らは離れて20ピクセル間隔をあけているので、第二に、画像ごとに20ピクセルを追加します。 第三に、0PXの代わりに10pxのためにあなたのイメージの初期XLOCを設定します。
第四に、あなたは画像ごとに20ピクセルを追加するには、スクロールビューのコンテンツサイズを設定してください。あなたはkNumImagesイメージを持っており、それぞれがkScrollObjWidthであれば、あなたはこのように行きます:
[scrollView setContentSize:CGSizeMake((kNumImages * (kScrollObjWidth+20)), kScrollObjHeight)];
これは、その後に動作するはずです!
これは、単なる勘ですが、それはcontentSizeがちょうど画面の幅よりも若干広くするように設定されている可能性があります。
正しい情報は画面幅にビュー内にレンダリングとUIScrollViewのは、残りの世話をするのですか?
たぶん、あなたはUIScrollViewののcontentInsetプロパティを試してみたい?
myScrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 10.0);
私はちょうど私が後世のために、ここで私は一緒に行くことになったソリューションを追加しようと思いました。長い間、私は-viewDidAppear
にフレームを調整するブライアンのソリューションを使用してきたが、これは見事に取り組んできました。 iOSのマルチタスクを導入しましたので、私は、アプリがバックグラウンドから再開したときに、スクロールビューのフレームが変更されます問題に実行してきました。この場合、-viewDidAppear
が呼び出されていませんでしたし、私は変更を逆にする適切なタイミングで呼び出されますデリゲートメソッドを見つけることができませんでした。だから、私はスクロールが私のビューコントローラのビューのサブビューを表示することに決め、これが問題を解決するように見えました。また、これは枠を変更する-viewDidAppear
を使用する必要がないという利点を持っている - あなたは、スクロールビューを作成した直後にそれを行うことができます。ここでの私の質問は >詳細を持っていますが、私もここに投稿します。
CGRect frame = CGRectMake(0, 0, 320, 460);
scrollView = [[UIScrollView alloc] initWithFrame:frame];
// I do some things with frame here
CGRect f = scrollView.frame;
f.size.width += PADDING; // PADDING is defined as 20 elsewhere
scrollView.frame = f;
[self.view addSubview:scrollView];
なゴUIScrollViewのフレーム、サブクラスUIScrollView、オーバーライドlayoutSubviewsの適用をオフセット種別に従い左寄せで記載する。
の考え方に基づき、以下の観測:
- 時zoomScale!=1、オフセットがゼロの場合は、左る際に使用することができます。
- 時zoomScale==1のときには、オフセットがゼロのときに見えるrectセンター
これにより,以下のようなコードは:
- (void) layoutSubviews
{
[super layoutSubviews];
// Find a reference point to calculate the offset:
CGRect bounds = self.bounds;
CGFloat pageGap = 8.f;
CGSize pageSize = bounds.size;
CGFloat pageWidth = pageSize.width;
CGFloat halfPageWidth = pageWidth / 2.f;
CGFloat scale = self.zoomScale;
CGRect visibleRect = CGRectMake(bounds.origin.x / scale, bounds.origin.y / scale, bounds.size.width / scale, bounds.size.height / scale);
CGFloat totalWidth = [self contentSize].width / scale;
CGFloat scrollWidth = totalWidth - visibleRect.size.width;
CGFloat scrollX = CGRectGetMidX(visibleRect) - visibleRect.size.width / 2.f;
CGFloat scrollPercentage = scrollX / scrollWidth;
CGFloat referencePoint = (totalWidth - pageWidth) * scrollPercentage + halfPageWidth;
// (use your own way to get all visible pages, each page is assumed to be inside a common container)
NSArray * visiblePages = [self visiblePages];
// Layout each visible page:
for (UIView * view in visiblePages)
{
NSInteger pageIndex = [self pageIndexForView:view]; // (use your own way to get the page index)
// make a gap between pages
CGFloat actualPageCenter = pageWidth * pageIndex + halfPageWidth;
CGFloat distanceFromRefPoint = actualPageCenter - referencePoint;
CGFloat numOfPageFromRefPoint = distanceFromRefPoint / pageWidth;
CGFloat offset = numOfPageFromRefPoint * pageGap;
CGFloat pageLeft = actualPageCenter - halfPageWidth + offset;
view.frame = CGRectMake(pageLeft, 0.f, pageSize.width, pageSize.height);
}
}