Kriteria
Kasus uji sederhana dapat menentukan warna latar belakang untuk tampilan ViewController dan memuat gambar serta topeng. Kemudian UITapGestureRecognizer ditambahkan ke tampilan ViewController dan ke UIImageView.
Saat menerapkan warna latar belakang ke tampilan ViewController, mudah untuk melihat apakah masking berfungsi.
Jika Anda kemudian mengetuk area yang tidak transparan, ketukan tersebut akan diterima oleh UIImageView, jika tidak, tampilan ViewController akan menerima ketukan tersebut.
Ukuran Gambar dan Gambar Mask
Dalam kebanyakan kasus, ukuran gambar dan gambar topeng atau setidaknya rasio aspek gambar dan gambar topeng adalah sama. Masuk akal untuk menggunakan contentMode
yang sama untuk menutupi UIImageView seperti untuk UIImageView asli, jika tidak, akan ada ketidakselarasan saat paling lambat mengubah mode konten di InterfaceBuilder.
Kasus Uji
Oleh karena itu, kasus ujinya akan terlihat seperti ini:
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!")
}
}
Kode ini sudah berjalan. Namun, seperti yang diharapkan, ketukan pada area transparan UIImageView juga muncul di sini.
Tampilan Gambar Khusus
Oleh karena itu kita memerlukan CustomImageView, yang kembali ketika mengklik piksel transparan yang bukan tanggung jawabnya.
Hal ini dapat dicapai dengan mengesampingkan metode ini:
func point(inside point: CGPoint,
with event: UIEvent?) -> Bool
lihat dokumentasi di sini: https://developer.apple.com/documentation/uikit/uiview/1622533-point
Mengembalikan nilai Boolean yang menunjukkan apakah penerima berisi titik yang ditentukan.
Sudah ada jawaban keren di SO, yang hanya sedikit diadaptasi: 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]
}
}
Jangan lupa untuk mengubah kelas khusus ImageView menjadi CustomImageView
di Xcode di pemeriksa identitas.
Jika sekarang Anda mengetuk area transparan, tampilan ViewController di latar belakang akan diketuk. Jika Anda mengetuk area yang tidak transparan, tampilan gambar kami akan menerima ketukan tersebut.
Demo
Berikut demo singkat kode di atas menggunakan gambar dan mask dari pertanyaan:
![demo](https://i.stack.imgur.com/tcpHZ.gif)
person
Stephan Schlecht
schedule
02.12.2018