iOS增加了TableViewCell中UIButton的触摸区域

时间:2015-10-13 11:39:00

标签: ios swift uitableview uibutton

我的UIButton

中有一个UITableViewCell

我创建了UIButton的子类覆盖pointInside函数:

var touchMargin:CGFloat = 20.0

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    let extendedArea = CGRectInset(self.bounds, -touchMargin, -touchMargin)
    return CGRectContainsPoint(extendedArea, point)
}

但是,触摸区域不会增加。
如果我稍微触摸UIButton之外,我会触摸表格单元格。

由于Button被放置在单元格中,此代码是否无效?
我该如何解决?

3 个答案:

答案 0 :(得分:9)

Swift 3

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layoutDirection="rtl"
    tools:background="@mipmap/bg">


    <RelativeLayout
        android:id="@+id/contactUsSaperator"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="5dp">

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_toLeftOf="@+id/gcontactUsHeader"
            android:background="#ffffff" />

        <TextView
            android:id="@+id/gcontactUsHeader"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerHorizontal="true"
            android:text="@string/contactUs"
            android:textColor="#ffffff" />

        <View
            android:layout_width="match_parent"
            android:layout_height="1dp"
            android:layout_centerVertical="true"
            android:layout_marginLeft="10dp"
            android:layout_marginRight="10dp"
            android:layout_toRightOf="@+id/gcontactUsHeader"
            android:background="#ffffff" />


    </RelativeLayout>


    <LinearLayout
        android:id="@+id/contactUsOpenHour"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:layout_below="@id/contactUsSaperator"
        android:layout_marginTop="17dp"
        android:layout_marginLeft="15dp"
        android:layout_marginRight="15dp"
        >

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/contactUsOpenHourText"
            android:textColor="@color/blueTextColor"
            android:textStyle="bold"
            android:textSize="16dp"
            android:layout_marginRight="10dp"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/contactUsOpenHourTuesdayWednesday"
            android:textColor="@color/blueTextColor"
            android:textSize="15dp"
            android:layout_marginRight="10dp"
            />
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/contactUsOpenHourThursday"
            android:textColor="@color/blueTextColor"
            android:textSize="15dp"
            android:layout_marginRight="10dp"
            />
        <TextView

            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/contactUsOpenHourFriday"
            android:textColor="@color/blueTextColor"
            android:textSize="15dp"
            android:layout_marginRight="10dp"
            />  

        <TextView            
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="35dp"
            android:text="@string/contactUsOpenHourPhone"
            android:textColor="@color/blueTextColor"
            android:textStyle="bold"
            android:textSize="16dp"
            android:layout_marginRight="10dp"
            />

        <FrameLayout
            android:layout_marginTop="25dp"
            android:layout_width="wrap_content"
            android:layout_height="150dp">

            <ImageView
                android:layout_width="wrap_content"
                android:layout_height="150dp"
                android:background="@mipmap/contact_us_tex_fild"
                android:scaleType="fitXY"
                />
            <ScrollView
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:layout_marginBottom="3dp"
                >
                <EditText
                    android:id="@+id/contactUsEditText"
                    android:layout_width="match_parent"
                    android:layout_height="match_parent"
                    android:hint="@string/contactHint"
                    android:textSize="15dp"

                    android:textColor="@color/blueTextColor"
                    android:textColorHint="@color/blueTextColor"
                    android:inputType="text"
                    />

            </ScrollView>

        </FrameLayout>

        <FrameLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="15dp"
            >
            <ImageView
                android:id="@+id/contactUsSendButton"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:src="@mipmap/button"
                />
            <TextView
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:text="@string/contacUsSendButton"
                android:layout_gravity="center"
                android:textColor="@color/blueTextColor"
                android:textSize="22dp"
                android:textStyle="bold"
                />

        </FrameLayout>

    </LinearLayout>

</LinearLayout>

您正在创建一个大小为100x100的// // ViewController.swift // test // // Created by David Seek on 9/29/16. // Copyright © 2016 David Seek. All rights reserved. // import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() let button = MyButton(frame: CGRect(x: 200, y: 200, width: 100, height: 100)) button.backgroundColor = UIColor.white button.addedTouchArea = 50 // any value you want button.addTarget(self, action:#selector(self.action), for: .touchUpInside) self.view.addSubview(button) } func action() { print("touched") } } class MyButton: UIButton { var addedTouchArea = CGFloat(0) override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { let newBound = CGRect( x: self.bounds.origin.x - addedTouchArea, y: self.bounds.origin.y - addedTouchArea, width: self.bounds.width + 2 * addedTouchArea, height: self.bounds.width + 2 * addedTouchArea ) return newBound.contains(point) } } ,而使用UIButton,您有一个UIButton - 仍然是光学尺寸100x100,但触摸区域为150x150。

Swift 2.X

.addedTouchArea

<强>的InterfaceBuilder

如果您使用class MyButton: UIButton { var addedTouchArea = CGFloat(0) override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool { let newBound = CGRect( x: self.bounds.origin.x - addedTouchArea, y: self.bounds.origin.y - addedTouchArea, width: self.bounds.width + 2 * addedTouchArea, height: self.bounds.width + 2 * addedTouchArea ) return newBound.contains(point) } } 设置了按钮,请将我们的InterfaceBuilder子类应用于您的按钮。

enter image description here

然后设置按钮的插座,f.e。名为buttonXY。并在UIButton内设置buttonXY.addedTouchArea = 50,f.e。

UITableViewCell

因为您要求viewDidLoad。它的工作方式完全相同。

在ViewController类中:

UITableViewCell

在你的Cell课程中:

extension ViewController: UITableViewDelegate, UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell") as! TableViewCell
        cell.selectionStyle = UITableViewCellSelectionStyle.none

        cell.myButton.addedTouchArea = 50 // any value you want
        tableView.rowHeight = 200

        return cell
    }
}

唯一值得注意的事情是:将插座设置为class TableViewCell: UITableViewCell { @IBOutlet weak var myButton: MyButton! override func awakeFromNib() { super.awakeFromNib() // Initialization code } override func setSelected(_ selected: Bool, animated: Bool) { super.setSelected(selected, animated: animated) // Configure the view for the selected state } @IBAction func myButtonAction(_ sender: AnyObject) { print("touched") } } 插座,即使我已将其声明为UIButton内的MyButton的子类。我不得不手动将插座改为InterfaceBuilderMyButton

答案 1 :(得分:6)

您应该在要放大的视图上覆盖hitTest。

e.g。

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
    if (!self.isUserInteractionEnabled || self.isHidden || self.alpha <= 0.01) {
        return nil;
    }
    CGRect touchRect = CGRectInset(self.bounds, -10, -10);
    if (CGRectContainsPoint(touchRect, point)) {
        //TODO!? check supviews
        return self;
    }
    return nil;
}

答案 2 :(得分:1)

首先,您需要创建UIButton子类:

class ButtonWithTouchSize: UIButton {

    var touchAreaPadding: UIEdgeInsets? = nil

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        if let inset = touchAreaPadding {
            let origin = CGPoint(x: 0 - inset.left, y: 0 - inset.top)
            let size = CGSize(width: inset.left + bounds.width + inset.right,
                              height: inset.top + bounds.height + inset.bottom)
            let rect = CGRect(origin: origin, size: size)
            return rect.contains(point)
        } else { 
            return super.point(inside: point, with: event)
        }
    }
}

如果你把ButtonWithTouchSize的一个实例直接放到UITableViewCell contentView中,你就可以得到它。但是如果你将这个实例包装在UITableViewCell contentView中的某个容器中,你也应该覆盖它的点(inside:with)方法:

class ContainerView: UIView {

    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
        return btn.point(inside: point, with: event)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        btn.frame = self.bounds
    }

    private let btn: ButtonWithTouchSize = ButtonWithTouchSize()

}

所以,总结一下......你应该为每个超级视图覆盖一个点(inside:with),其大小为lessThanOrEqual to button size