我的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被放置在单元格中,此代码是否无效?
我该如何解决?
答案 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
子类应用于您的按钮。
然后设置按钮的插座,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的子类。我不得不手动将插座改为InterfaceBuilder
! MyButton
答案 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