web-dev-qa-db-ja.com

iOS 5でのUISegmentedControlのカスタマイズ

これが私の問題です。次のように背景とディバイダーの画像を設定して、UISegmentedControlをカスタマイズしています。

[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];

[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];

viewDidLoad内で最初のセグメントを選択しようとすると

self.segmentedControl.selectedIndex = 1;

私は以下の奇妙なものを手に入れました:

enter image description here

の代わりに:

enter image description here

これがバグかどうか誰もが知っていますか?バグレポートをどのように提供できますか?そうでない場合、私のコードで何が問題になる可能性がありますか?

27
nimeshdesai

いくつかのテストを行い、カスタマイズのためにいくつかの異なる場所を試した後、これは確かにバグであると思います。

非常に単純なストレートUISegmentedControlを使用しても、これは(Xcode 4.3.1、iOS 5.1を使用して)取得されるものです。

コードの中央の要素を起動して選択した後: After launching and selecting the middle element in code

ユーザーが離れてクリックして中央の要素をクリックした後: After user-clicked away and clicking back on middle element

セパレータには幅3pxの画像を使用し、背景には幅1pxの画像を使用しました。

編集:回避策を見つけたと思います。次のように、viewDidLoadで実行するのではなく、要素を選択するための命令をキューに入れてみてください。

dispatch_async(dispatch_get_main_queue(),^{
   self.segmentedControl.selectedSegmentIndex = 1;
});

上記の例では、その命令をキューに入れると、正常に機能します。

10

CapInsetsの画像は正しくないと思います。 http://www.raywenderlich.com/4344/user-interface-customization-in-ios-5 の例を2倍にしてください

以下は、クイックリファレンス用のチュートリアルのコードです。

UIImage *segmentSelected = [[UIImage imageNamed:@"segcontrol_sel.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentUnselected = [[UIImage imageNamed:@"segcontrol_uns.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentSelectedUnselected = [UIImage imageNamed:@"segcontrol_sel-uns.png"];
UIImage *segUnselectedSelected = [UIImage imageNamed:@"segcontrol_uns-sel.png"];
UIImage *segmentUnselectedUnselected = [UIImage imageNamed:@"segcontrol_uns-uns.png"];

[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected forLeftSegmentState:UIControlStateSelected rightSegmentState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segUnselectedSelected forLeftSegmentState:UIControlStateNormal rightSegmentState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
4
flypig

サイズ変更可能な画像を設定しようとしましたか?

例えば:

UIImage *segmentSelected = [[UIImage imageNamed:@"SegmentSelectedImage"] resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
1
Julien

多くの実験をした後、私は問題を解決する方法を見つけました。

問題は、セグメントの幅設定が正しくないことです。

最初のポイント-個々のセグメントの幅を設定する前に、UIをカスタマイズする必要があります。

2番目のポイント-仕切りの幅を数える必要があります。これは非常に重要です。カスタマイズを行う場合、仕切りはUISegmentedControl要素の一部です。仕切りはオーバーレイではありません。仕切りの幅も数える必要があります。

3番目のポイント-セグメントに幅の設定方法を使用する場合、セグメントの幅にディバイダーの幅を含める必要はありません。

上記のルールに従えば、完全にカスタマイズされたUISegmentedControlを取得できます。

1
user403015

viewDidLoadよりも前に外観設定を初期化してみてください。私が見たデモンストレーションでは、これは通常application:didFinishLaunchingWithOptions:、ただし、カスタマイズされたビューを含むnibをロードする前のどの時点でも機能するはずです。

0
Casey Fleser

同じ問題があり、別の方法で解決しました。私はこのコード行にコメントしました:

self.pageController.segmentedControlStyle = UISegmentedControlStyleBar;

そして、セグメントバーはビューを通常の状態に変更しました。

0
Wert1go