12

iPhoneアプリにUIButtonがあります。サイズを100x100に設定しました。

ボタンに表示したい400x200の画像があります。

ボタンはまだ100x100のままである必要があります...そして私は画像をフィットするように縮小したいです...しかし正しいアスペクト比を維持します。

それが「アスペクトフィット」の用途だと思いました。

setImageまたはsetBackgroundImageに画像を含めますか?

ボタンにAspectFitを設定しますか?または画像?または背景画像?

(サイズを大きくするには小さい画像が必要です。大きい画像はサイズを小さくする必要があります。ボタンは常に100x100のままにしてください。)

私は上記のすべての無数の組み合わせを試しました...そして私はすべてを同時に機能させることができないようです:

  • ボタンのサイズを100x100に変更しないでください。
  • 画像のアスペクト比を壊さないでください。
  • ボタンに合うように、常に小さな画像を増やしてください。
  • ボタンに合うように、常に大きな画像を減らしてください。
  • 画像の端をクリップしないでください。
  • 「すべてのUIimagesにUIButtonを配置する」ハックは必要ありません。
  • 新しいフレームワークメソッドを使用するためだけに、全員がv4.2.1にアップグレードする必要はありません。

非常に多くのアプリがあり、完全に機能する画像ボタンがたくさんあります...この非常に単純で非常に一般的なことを理解できないとは信じられません。

うーん。

4

8 に答える 8

12

UIButton が壊れています。それが短い答えです。image および backgroundImage プロパティのUIImageViews は、設定を尊重しませんUIViewContentMode。それらは読み取り専用のプロパティであり、UIImageこれらの UIImageViews のコンテンツはメソッドを介して設定できsetImage:ますsetBackgroundImage:が、コンテンツ モードは設定できません。

解決策は、最初に適切なサイズの画像をバンドルに提供するか、UIImageView を配置して、必要な方法で構成し、その上に明確な「カスタム」UIButton を配置することです。これは、あなたが見たすべての派手なプロのアプリが使用したハックです, 私は約束します. 私たちは皆それをしなければなりません。

于 2010-12-21T21:07:45.007 に答える
4

これを正しく行うには、実際にプログラムで画像のサイズを変更して操作し、目的のアスペクト比を取得します。これにより、ビュー階層をハッキングする必要がなくなり、すべての再描画ではなく、単一の操作に対するパフォーマンスの低下も軽減されます。

この(テストされていない)コードは、私が何を意味するかを説明するのに役立つはずです。

CGSize imageSize = image.size;
CGFloat currentAspect = imageSize.width / imageSize.height;

// for purposes of illustration
CGFloat targetWidth = 100;
CGFloat targetHeight = 100;
CGFloat targetAspect = targetWidth / targetHeight;

CGFloat newWidth, newHeight;

if (currentAspect > targetAspect) {
    // width will end up at 100, height needs to be smaller
    newWidth = targetWidth;
    newHeight = targetWidth / currentAspect;
} else {
    // height will end up at 100, width needs to be smaller
    newHeight = targetHeight;
    newWidth = targetHeight * currentAspect;
}

size_t bytesPerPixel = 4;

// although the image will be resized to { newWidth, newHeight }, it needs
// to be padded with empty space to provide the aspect fit behavior
//
// use calloc() to clear the data as it's allocated
void *imageData = calloc(targetWidth * targetHeight, bytesPerPixel);

if (!imageData) {
    // error out
    return;
}

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
if (!colorSpace) {
    // error out
    return;
}

CGContextRef context = CGBitmapContextCreate(
    imageData,
    targetWidth,
    targetHeight,
    8, // bits per component
    targetWidth * bytesPerPixel, // bytes per row
    colorSpace,
    kCGBitmapByteOrder32Host | kCGImageAlphaPremultipliedFirst
);

CGColorSpaceRelease(colorSpace);

// now we have a context to draw the original image into
// in doing so, we want to center it, so prepare the geometry
CGRect drawRect = CGRectMake(
    floor((targetWidth - newWidth) / 2),
    floor((targetHeight - newHeight) / 2),
    round(newWidth),
    round(newHeight)
);

CGContextDrawImage(context, drawRect, image.CGImage);

// now that the bitmap context contains the aspect fit image with transparency
// letterboxing, we want to pull out a new image from it
CGImageRef newImage = CGBitmapContextCreateImage(context);

// destroy the temporary context
CGContextRelease(context);
free(imageData);

// and, finally, create a new UIImage
UIImage *newUIImage = [UIImage imageWithCGImage:newImage];
CGImageRelease(newImage);

その一部が不明な場合はお知らせください。

于 2010-12-21T21:38:56.020 に答える
2

ダンが言おうとしているのは(しかし決して言わずに)これを行うことだと思います:

  • 「一時画像」を使用してサイズ変更を行います。
  • temp-image は ASPECT FIT と HIDDEN に設定する必要があります。
  • ボタンが目的のサイズに設定されていることを確認し、アスペクト フィットに設定しないでください。
// フレームをボタンと同じサイズにします
CGRect aFrame = CGRectMake(0, 0, myButton.frame.size.width, myButton.frame.size.height);

// temp-image をボタンのサイズに設定します
imgTemp.frame = aFrame;

// 画像を一時画像に入れます
imgTemp.image = anImage;

// そのサイズ変更された一時画像をボタンにコピーします
[myButton setBackgroundImage:tempImage forState:UIControlStateNormal];
于 2010-12-21T21:00:51.200 に答える
2

私の試みはどれもうまくいかなかったので....

代わりにこれを尋ねる必要があるかもしれません。UIButton を使用する場合:

setBackgroundImage の代わりに setImage を使用するのはいつですか? (なんで両方あるの?)

「センター」の代わりに「アスペクト フィット」を使用するのはいつですか? (それぞれ「アスペクト比を維持する」と「何もサイズを変更しない」と期待しているときに、両方の画像が引き伸ばされているように見えるのはなぜですか。)

そして大きな疑問: なぜ、これほどありふれたことが… こんなに大混乱なのか?

次のような回避策を見つけることができれば、すべて解決されます。代わりに UIImage を使用して、TAPS を検出してください。(しかし、それはコードの大きな悪夢でさえあるようです。)

アップルさん、あなたが私の仕事を楽にしようとしたのなら、400 倍も混乱させたことになります。

于 2010-12-21T21:59:16.443 に答える
1

ボタンの上にイメージビューを配置し、イメージをボタンではなくイメージビューに設定します。

ではごきげんよう。

于 2010-12-21T17:20:43.897 に答える
1

画像に含まれるコンテンツの縦横比を維持しながら、画像のサイズを 100x100 に変更します。次に、UIButton の backgroundImage プロパティを画像に設定します。

于 2010-12-21T18:52:54.213 に答える