เกณฑ์
กรณีทดสอบอย่างง่ายสามารถกำหนดสีพื้นหลังสำหรับมุมมองของ ViewController และโหลดรูปภาพและมาสก์ จากนั้น UITapGestureRecognizer จะถูกเพิ่มในมุมมอง ViewController และใน UIImageView
เมื่อใช้สีพื้นหลังกับมุมมอง ViewController จะง่ายต่อการดูว่าการมาสก์ใช้งานได้หรือไม่
หากคุณแตะบนพื้นที่ที่ไม่โปร่งใส UIImageView ควรได้รับการแตะ มิฉะนั้นมุมมอง ViewController ควรได้รับการแตะ
ขนาดรูปภาพและมาสก์
ในกรณีส่วนใหญ่ ขนาดรูปภาพและรูปภาพมาสก์หรืออย่างน้อยก็อัตราส่วนภาพของรูปภาพและรูปภาพมาสก์จะเท่ากัน มันสมเหตุสมผลที่จะใช้ contentMode
เดียวกันสำหรับการมาสก์ของ UIImageView เช่นเดียวกับ UIImageView ดั้งเดิม มิฉะนั้นจะมีการวางแนวที่ไม่ตรงเมื่อเปลี่ยนโหมดเนื้อหาใน InterfaceBuilder เป็นอย่างล่าสุด
กรณีทดสอบ
ดังนั้นกรณีทดสอบอาจมีลักษณะดังนี้:
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
private let maskView = UIImageView()
override func viewDidLoad() {
super.viewDidLoad()
self.imageView.image = UIImage(named: "testimage")
self.maskView.image = UIImage(named: "mask")
self.imageView.mask = maskView
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(backgroundTapped))
self.view.addGestureRecognizer(tapGestureRecognizer)
let imageViewGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(iamgeViewTapped))
self.imageView.addGestureRecognizer(imageViewGestureRecognizer)
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.maskView.contentMode = self.imageView.contentMode
self.maskView.frame = self.imageView.bounds
}
@objc private func backgroundTapped() {
print ("background tapped!")
}
@objc private func iamgeViewTapped() {
print ("image view tapped!")
}
}
รหัสนี้กำลังทำงานอยู่แล้ว ตามที่คาดไว้ การแตะที่พื้นที่โปร่งใสของ UIImageView ก็มาถึงที่นี่เช่นกัน
CustomImageView
ดังนั้นเราจึงจำเป็นต้องมี CustomImageView ซึ่งจะส่งคืนเมื่อคลิกที่พิกเซลโปร่งใสซึ่งจะไม่รับผิดชอบ
ซึ่งสามารถทำได้โดยการแทนที่วิธีนี้:
func point(inside point: CGPoint,
with event: UIEvent?) -> Bool
ดูเอกสารที่นี่: https://developer.apple.com/documentation/uikit/uiview/1622533-point
ส่งกลับค่าบูลีนที่ระบุว่าผู้รับมีจุดที่ระบุหรือไม่
มีคำตอบที่ยอดเยี่ยมนี้อยู่แล้วใน SO ซึ่งปรับเปลี่ยนเล็กน้อย: https://stackoverflow.com/a/27923457
import UIKit
class CustomImageView: UIImageView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return self.alphaFromPoint(point: point) > 32
}
private func alphaFromPoint(point: CGPoint) -> UInt8 {
var pixel: [UInt8] = [0, 0, 0, 0]
let colorSpace = CGColorSpaceCreateDeviceRGB();
let alphaInfo = CGBitmapInfo(rawValue: CGImageAlphaInfo.premultipliedLast.rawValue)
if let context = CGContext(data: &pixel,
width: 1,
height: 1,
bitsPerComponent: 8,
bytesPerRow: 4,
space: colorSpace,
bitmapInfo: alphaInfo.rawValue) {
context.translateBy(x: -point.x, y: -point.y)
self.layer.render(in: context)
}
return pixel[3]
}
}
อย่าลืมเปลี่ยนคลาสที่กำหนดเองของ ImageView เป็น CustomImageView
ใน Xcode ในตัวตรวจสอบข้อมูลประจำตัว
หากคุณแตะที่พื้นที่โปร่งใส มุมมองของ ViewController ในพื้นหลังจะได้รับการแตะ หากคุณแตะที่พื้นที่ที่ไม่โปร่งใส มุมมองรูปภาพของเราจะได้รับการแตะ
สาธิต
นี่คือตัวอย่างสั้นๆ ของโค้ดด้านบนโดยใช้รูปภาพและมาสก์จากคำถาม:
![สาธิต](https://i.stack.imgur.com/tcpHZ.gif)
person
Stephan Schlecht
schedule
02.12.2018