ios - How to add "inner padding" into custom view so that its size will become smaller visually yet able retain its touchable area?
问题描述
I have the a custom view with the following simple constraint
- Height 88
- Width 88
- Center X
- Center Y
I tend to make it as circle visually. Here's my code.
extension UIView {
func asCircle() {
self.layer.cornerRadius = self.frame.width / 2;
self.layer.masksToBounds = true
}
}
class ViewController: UIViewController {
@IBOutlet weak var circleView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
circleView.backgroundColor = .red
circleView.asCircle()
// 1. create a gesture recognizer (tap gesture)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
// 2. add the gesture recognizer to a view
circleView.addGestureRecognizer(tapGesture)
// Currently, the touchable area of circleView is 88 x 88
}
// 3. this method is called when a tap is recognized
@objc func handleTap(sender: UITapGestureRecognizer) {
print("tap")
}
}
What I would like to have is
- The touchable area of the circle remains 88 x 88
- The red circle however will look visually as 22 x 22
I add the following code, but it doesn't make any change
// We use 33, because 88-33-33 = 22
circleView.layoutMargins = UIEdgeInsets(top: 33, left: 33, bottom: 33, right: 33)
Does anyone know how to achieve so? Preferable without overriding draw function, or add an additional UIView
as subview.
解决方案
将图层添加到您的 circleView 并清除 circleView 示例:
extension UIView {
func asCircle() {
self.layer.cornerRadius = self.frame.width / 2;
self.layer.masksToBounds = true
}
}
class ViewController: UIViewController {
var circleView: UIView = {
let circle = UIView()
circle.translatesAutoresizingMaskIntoConstraints = false
return circle
}()
override func viewDidLoad() {
super.viewDidLoad()
self.view.addSubview(self.circleView)
circleView.backgroundColor = .clear
self.circleView.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
self.circleView.centerYAnchor.constraint(equalTo: self.view.centerYAnchor).isActive = true
let width = NSLayoutConstraint(item: self.circleView, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .width, multiplier: 1.0, constant: 88)
let height = NSLayoutConstraint(item: self.circleView, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .height, multiplier: 1.0, constant: 88)
self.circleView.addConstraints([width, height])
self.circleView.layoutIfNeeded()
// 1. create a gesture recognizer (tap gesture)
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap(sender:)))
// 2. add the gesture recognizer to a view
circleView.addGestureRecognizer(tapGesture)
// Currently, the touchable area of circleView is 88 x 88
}
// 3. this method is called when a tap is recognized
@objc func handleTap(sender: UITapGestureRecognizer) {
print("tap")
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let layer = CALayer()
layer.backgroundColor = UIColor.blue.cgColor
layer.frame = CGRect(x: 0, y: 0, width: 22, height: 22)
self.circleView.layer.insertSublayer(layer, at: 1)
layer.cornerRadius = layer.frame.height / 2
layer.position = CGPoint(x: self.circleView.frame.height / 2, y: self.circleView.frame.height / 2)
}
}
推荐阅读
- html - 当大量文本后没有更多文本时,如何摆脱网格中的多余空间?
- c# - C# & nginx - 上游超时
- testing - 如何将数据值添加到柏树测试
- visual-studio - 如何在 Wix Toolkit 的 MSI 项目的模板摘要中插入 Intel64 或 x64?
- powershell - 将内容文件部署到 AD 用户
- scala - 您可以将 scala 中的数据帧插入 Teradata 存储过程吗?
- flutter - 颤动页面过渡 - 为第 2 页滑入和第 1 页滑出创建效果
- wordpress - 如何将条件字段联系表 7 分组到一个变量中(条件字段联系表 7-Wordpress)
- powerbi - 使用多个 SSAS 多维数据集作为 PowerBI 源进行报告
- java - 在 Java 中删除特定于语言环境的标点符号