23

ページング モードの UIScrollView は、ページが隙間なく隣り合って配置されていることを前提としています。ただし、写真アプリで写真を開いて写真をスワイプすると、ページ間にギャップがあることがわかります。このギャップも欲しい。

既存の解決策があれば探しています。または、以下で説明したもの以外のページギャップの実装に関するさらに奇妙なアイデアを探しています。それとも、私が見逃している明らかな簡単な方法がありますか?

明確にするために、スクロール中にのみギャップを表示したいので、ページコンテンツを単純に挿入することはできません。


scrollViewDidScroll私の計画は、(右にスクロールしていると仮定して) 最初にターゲット ページがページ境界の右側にわずかにオフセットされ、ターゲット ページに到達するまでに、ページ コンテンツをコールバック内から移動しようとすることです。適切な位置に戻り、ソース ページは境界線の左側にわずかにずれています。(または、物事を継続的に移動する代わりに、ページ間のちょうど中間など、オフセットをシフトする方がよいでしょう。)

私はScrollingMadness の記事 + 例の著者であり、ここで何人かの人々に紹介しています。プログラムによるズームを実装し、写真内のズームとスクロールを写真間のページングと連携させました。だから私は UIScrollView で遊ぶ方法を知っており、高度なものを探しています。

TTScrollView を指ささないでください。私はすでに多くの人にそれを指摘しましたが、ネイティブの UIScrollView の動作とはかけ離れていると感じており、自分のプロジェクトでは使用したくありません。

4

8 に答える 8

27

この回答はかなり古いことに注意してください。基本的な概念は引き続き機能しますが、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];

これがコンパイルされない場合はお詫びします。ランドスケープ アプリでテストし、手動で編集してポートレートに戻しました。私はあなたがアイデアを得ると確信しています。これは、全画面表示の場合に常に当てはまるスーパービューのクリッピングに依存しています。

于 2009-05-12T05:56:54.130 に答える
22

したがって、上記の回答にコメントを投稿するのに十分な「担当者」がいません。その答えは正しいですが、注意すべき大きな問題があります。

UINavigationController の一部である viewController で UIScrollView を使用している場合、ナビゲーション コントローラーは scrollView のフレームのサイズを変更します。

つまり、UINavigationController を使用して異なるビューを切り替えるアプリがあります。scrollView を持つ viewController をプッシュし、viewController の -init メソッドでこの scrollView を作成します。(0, 0, 340, 480) のフレームを割り当てます。

次に、viewController の -viewDidAppear メソッドに移動し、作成した scrollView のフレームを取得します。幅が 320 ピクセルに縮小されていることがわかります。そのため、ページングは​​正しく機能しません。scrollView は 340 ピクセル移動すると予想されますが、代わりに 320 ピクセル移動します。

UINavigationController は、サブビューをいじることで少し有名です。それらを移動し、ナビゲーション バーに合わせてサイズを変更します。要するに、チーム プレーヤーではありません。この場合は特にそうです。Web 上の他の場所では、ビューのサイズと位置を正確に制御する必要がある場合は、UINavigationController を使用しないことをお勧めします。代わりに、UINavigationBar に基づいて独自の navigationController クラスを作成することをお勧めします。

それは大変な作業です。幸いなことに、もっと簡単な解決策があります。viewController の -viewDidAppear メソッドで scrollView のフレームを設定します。この時点で、UINavigationController はフレームの処理を完了しているため、本来あるべき状態にリセットすると、scrollView が適切に動作します。

これは OS 3.0 に関連しています。3.1 または 2.2.1 はテストしていません。また、Apple にバグ レポートを提出し、「-shouldAutoarrangeSubviews」などの BOOL を使用して UINavigationController を変更することを提案しました。これにより、そのクラスがサブビューから手を離さないようにすることができます。

それが実現するまで、上記の修正により、UINavigationController 内のページ分割された UIScrollView にギャップが生じます。

于 2009-07-18T01:40:01.987 に答える
7

Apple は、iphone 開発者プログラムのすべてのメンバーに 2010 WWDC セッション ビデオをリリースしました。議論されたトピックの 1 つは、彼らが写真アプリを作成した方法です!!! 彼らは非常によく似たアプリを段階的に構築し、すべてのコードを無料で利用できるようにしました。

プライベート API も使用しません。サンプルコードのダウンロードへのリンクです。アクセスするには、おそらくログインする必要があります。

http://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?code=y&source=x&bundleID=20645

また、iTunes WWDC ページへのリンクは次のとおりです。

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

于 2010-06-20T19:39:42.420 に答える
4

これを行う方法は、あなたが言ったように、いくつかのことを組み合わせたものです。

画像間に 20 ピクセルのギャップが必要な場合は、次のことを行う必要があります。

まず、スクロール ビューの合計幅を 20 ピクセル拡大し、左に 10 ピクセル移動します。

次に、画像の xLoc をレイアウトするときは、画像ごとに 20px を追加して、20px の間隔を空けるようにします。3 番目に、画像の初期 xLoc を 0px ではなく 10px に設定します。

4 つ目は、スクロール ビューのコンテンツ サイズを設定して、画像ごとに 20 ピクセルを追加することです。したがって、kNumImages の画像があり、それぞれが kScrollObjWidth である場合、次のようになります。

[scrollView setContentSize:CGSizeMake((kNumImages * (kScrollObjWidth+20)),  kScrollObjHeight)];

その後はうまくいくはずです!

于 2009-06-12T15:53:08.807 に答える
0

後世のために、最終的に使用したソリューションをここに追加すると思いました。長い間、フレームを調整する Bryan のソリューションを使用してきましたが-viewDidAppear、これは見事に機能しています。ただし、iOS でマルチタスクが導入されて以来、アプリがバックグラウンドから再開したときにスクロール ビュー フレームが変更されるという問題が発生しています。この場合、-viewDidAppearは呼び出されておらず、変更を元に戻すために適切なタイミングで呼び出されるデリゲート メソッドが見つかりませんでした。そこで、スクロール ビューを View Controller のビューのサブビューにすることにしました。これで問題が解決したようです。これには、 を使用してフレームを変更する必要がないという利点もあり-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];
于 2011-12-30T14:11:18.930 に答える
0

UIScrollView の contentInset プロパティを試してみませんか?

myScrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 10.0);
于 2009-05-11T22:28:07.263 に答える