web-dev-qa-db-ja.com

Xcodeストーリーボードで伸縮可能な画像を使用する

ビューコントローラーをレイアウトするためにストーリーボードを使用していますが、ボタンに伸縮可能な画像を使用したいと思います(異なるサイズの複数の画像を生成する必要がないように)。

これは、コードを書かずにストーリーボードで直接行うことは可能ですか?すべてのグラフィックにストーリーボードを使用して、UIからコードをクリーンに保つ可能性を本当に望んでいますが、ここではうまくいかないようです。

それが不可能な場合、それ以外の場合は何を提案しますか?

33
Joel

iOS 7以降のアップデート
iOS 7以降は、アセットカタログを介してネイティブに伸縮可能な画像をサポートします。資産カタログを使用して、画像のスライス方法とスケーリング方法(ストレッチまたはタイル)を指定できるようになりました。画像のこれらの資産カタログ属性は、ストーリーボードにすぐに反映されます。すばらしい新しい改善。詳細については、 アセットカタログのAppleのドキュメント を参照してください。

7より前のiOSバージョンにデプロイする場合:
それはあまり知られていない事実ですが、Interface Builder/Storyboardと属性インスペクターのストレッチプロパティのみを使用して、画像のキャップインセットを絶対に設定できます。元の答えを Victor に感謝します。

UIImageの属性インスペクターのストレッチプロパティを見ると、XとYの値は、イメージの幅と高さ全体に対するストレッチ開始点の位置です。値0.5は、画像の中央のポイントを意味します。

幅と高さは、画像サイズに対する伸縮可能領域のサイズです。したがって、幅を1/imageWidthの値に設定すると、伸縮可能な領域の幅が1ピクセルに設定されます。

ほとんどの伸縮可能な画像は中央から伸縮するため、通常、X、Y、幅、および高さにこれらの値を使用すると機能します。

X = 0.5
Y = 0.5
Width = 1/imageWidth
Height = 1/imageHeight

注:ストレッチする画像が非常に小さい場合を除き、これは幅と高さのプロパティが非常に小さく(0.008など)、代わりに0.0を使用できることを意味します。したがって、実際には、0.5、0.5、0.0、0.0は、X、Y、幅、高さに対してほぼ常に機能します。

幅と高さに対して0.0が機能しない少数の場合、これは、電卓を使用してこれらの値をIBに設定する必要があることを意味します。ただし、IB(WYSIWYG)で結果の引き伸ばされた画像を見ることができるので、プログラムで設定するよりも一般的に望ましいと思います。

Stretchable image attributes

更新:一部の人々は、上記の提案を使用してストーリーボードで画像をストレッチすることはできますが、iOS7の時点でもボタン上の画像のストレッチはまだ壊れていると指摘しています。心配することはありませんが、これはコントロール状態のキャップインセットを設定するUIButtonカテゴリーを作成することで簡単に対処できます:

@implementation UIButton (Stretchable)

/* Automatically set cap insets for the background image. This assumes that
   the image is a standard slice size with a 1 px stretchable interior */
- (void)setBackgroundImageStretchableForState:(UIControlState)controlState
{
    UIImage *image = [self backgroundImageForState:controlState];
    if (image)
    {
       CGFloat capWidth =  floorf(image.size.width / 2);
       CGFloat capHeight =  floorf(image.size.height / 2);
       UIImage *capImage = [image resizableImageWithCapInsets:
                     UIEdgeInsetsMake(capHeight, capWidth, capHeight, capWidth)];

       [self setBackgroundImage:capImage forState:controlState];
    }
}

このカテゴリを使用すると、Storyboardを介してボタンに伸縮可能な画像を設定し、-setBackgroundImageStretchableForState:-viewDidLoadを呼び出すことで、ボタンが適切に伸縮することを簡単に確認できます。ビュー階層を反復処理することで、ビュー内の多数のボタンに対してもこれを簡単に行うことができます。

NSPredicate *predicate = 
    [NSPredicate predicateWithFormat:@"self isKindOfClass:%@",[UIButton class]];
NSArray *buttons = [self.view.subviews filteredArrayUsingPredicate:predicate];
for (UIButton *button in buttons)
   [button setBackgroundImageStretchableForState:UIControlStateNormal];

これは、自動的にこれを行うUIButtonサブクラスを持つほどは良くありませんが(UIButtonはクラスクラスターであるため、サブクラス化は実用的ではありません)、ほぼ同じです。 viewDidLoadにボイラープレートコードを少し追加するだけの機能-Storyboardですべてのボタン画像を設定し、それらを適切に引き伸ばすことができます。

73
memmons

Xcode 6(およびiOS7 +ターゲット)を使用すると、画像アセットを操作するときにスライスエディターを使用できます。 Editor-> Show Slicingメニューでスライスモードを切り替えるか、Show Slicingを押しますエディターで特定の画像を選択するときのボタン(下に表示)。

Show Slicing button

その後、特定の表示縮尺の画像を選択し、ルールをドラッグするか、インセット値を手動で編集できます。

Rules

その後、Interface Builderでこの画像を選択できます。たとえば、私はUIButtonBackground Imageに使用します(IBボタンの表現は悪く見えるかもしれませんが、実行中はOKです)。

私のボタンはよく見えます(iOS 7.1シミュレーターとiOS 8デバイスを実行しています)。

enter image description here

このApple doc link が役立つ可能性があります。

14
Anton Gaenko

XCodeの5.0 Interface Builderでアセットカタログを使用して実行できます。画像アセットを作成します(アセットカタログがまだない場合は、次のように作成できます。

  1. File-> New-> File-> Resources-> Asset Catalog
  2. 次にEditor-> New Image Set
  3. IdiomおよびScaleの画像を設定します
  4. 次に、Show Slicingボタンを使用して、必要に応じてスライスを設定します。

チェックAppleこちらのドキュメント: 開発者Apple:Asset Catalogヘルプ その後、ボタンの背景画像を要求されたアセットとして設定するだけです。

編集:iOS7でのみ希望どおりに動作することを言及するのを忘れました

11
Lorenzo NEY

私がしたことは次のとおりです。ボタンのアウトレットを設定して接続し、viewDidLoadでこれを行いました。

[self.someButton setBackgroundImage:[[self.someButton backgroundImageForState:UIControlStateNormal] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 4, 3)] forState:UIControlStateNormal];

これにより、ストーリーボードで設定した画像が再利用されるため、インセットが変更されない限り、ある色から別の色に変更しても機能します。

これらの多くのことを持っているビューのために、私はこれをしました:

for (UIView * subview in self.view.subviews) {
        if ([subview isKindOfClass:[UIImageView class]] && subview.tag == 10) {
            UIImageView* textFieldImageBackground = (UIImageView*)subview;
            textFieldImageBackground.image = [textFieldImageBackground.image stretchableImageWithLeftCapWidth:7 topCapHeight:5];
        } else if([subview isKindOfClass:[UIButton  class]] && subview.tag == 11) {
            UIButton * button = (UIButton*)subview;
            [button setBackgroundImage:[[button backgroundImageForState:UIControlStateNormal] resizableImageWithCapInsets:UIEdgeInsetsMake(3, 3, 4, 3)] forState:UIControlStateNormal];
        }
    }

ストレッチしたいすべてのタグにタグを設定していることに注意してください。

私はあなたと同じ船に乗っていますが、これらの非常にUI中心のことをストーリーボード自体に設定できることを楽しみにしています。

2

Xcodeスライス機能を使用して、画像のサイズ変更可能な中央領域の寸法を指定し、オプションでエンドキャップを指定します。エンドキャップは、サイズ変更可能な領域で塗りつぶしてはならない画像の領域です。 アセットカタログについて を参照してください

0
backslash112