web-dev-qa-db-ja.com

UIButtonのタップ領域を増やすにはどうすればよいですか?

自動レイアウトでUIButtonを使用します。画像が小さい場合、タップ領域も小さくなります。これを修正するいくつかのアプローチを想像できます。

  1. 画像サイズを大きくします。つまり、画像の周囲に透明な領域を配置します。画像を配置するとき、余分な透明な境界線を覚えておく必要があるため、これは良くありません。
  2. cGRectInsetを使用して、サイズを増やします。自動レイアウトを使用すると元の画像サイズにフォールバックするため、これは自動レイアウトではうまく機能しません。

上記の2つのアプローチのほかに、UIButtonのタップ領域を増やすためのより良いソリューションがありますか?

47
Sven Bauer

ボタンのコンテンツインセットを調整するだけで、目的のサイズを取得できます。コードでは、次のようになります。

button.contentEdgeInsets = UIEdgeInsets(上:12、左:16、下:12、右:16)

//または、特に画像の周囲を調整したい場合は、代わりにbutton.imageEdgeInsetsを使用します

インターフェイスビルダーでは、次のようになります。

interface builder

52
Travis

非常に簡単。カスタムUIButtonクラスを作成します。次に、pointInside ...メソッドをオーバーライドし、必要に応じて値を変更します。

#import "CustomButton.h"

@implementation CustomButton

-(BOOL) pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
    CGRect newArea = CGRectMake(self.bounds.Origin.x - 10, self.bounds.Origin.y - 10, self.bounds.size.width + 20, self.bounds.size.height + 20);

    return CGRectContainsPoint(newArea, point);
}
@end

すべての側面で10ポイント以上のタッチ領域が必要です。

ストーリーボードまたはコードでEdgeInsetsボタンを設定できます。ボタンのサイズは、ボタンに設定された画像よりも高さと幅が大きくなければなりません。

注:Xcode8以降、コンテンツインセットの設定はサイズインスペクターで利用可能です UIEdgeInseton UIButton

または、画像ビューをタップして操作するために、タップジェスチャを使用して画像ビューを使用することもできます。ジェスチャを機能させるために、ストーリーボードの画像ビューの[ユーザーインタラクションを有効にする]をオンにしてください。設定する画像よりも画像ビューを大きくして、画像を設定します。次に、画像ビュー画像のモードをストーリーボード/インターフェイスビルダーの中心に設定します。

Using image view with tap action and image set on it as center mode 画像をタップしてアクションを実行できます。

役に立てば幸いです。

9
user2094867

Syedのソリューションは、自動レイアウトでもうまく機能することを確認しています。 Swift 4.xバージョン:

import UIKit

class BeepSmallButton: UIButton {

    // MARK: - Functions

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        let newArea = CGRect(
            x: self.bounds.Origin.x - 5.0,
            y: self.bounds.Origin.y - 5.0,
            width: self.bounds.size.width + 10.0,
            height: self.bounds.size.height + 20.0
        )
        return newArea.contains(point)
    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
8
Glenn

Swift 4•Xcode 9

次のようにプログラムで選択できます-

画像の場合-

button.imageEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)

タイトルの場合-

button.titleEdgeInsets = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8)
3
Jack

UIButtonをサブクラス化し、この関数を追加します

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
    let verticalInset = CGFloat(10)
    let horizontalInset = CGFloat(10)

    let largerArea = CGRect(
        x: self.bounds.Origin.x - horizontalInset,
        y: self.bounds.Origin.y - verticalInset,
        width: self.bounds.size.width + horizontalInset*2,
        height: self.bounds.size.height + verticalInset*2
    )

    return largerArea.contains(point)
}
1
Lucas Chwe