Cara memotong UIImage untuk menutupi di Swift

Saya memiliki UIImage yang saya tutupi menggunakan UIImage lain. Satu-satunya masalah adalah area di luar UIImage bertopeng masih dapat berinteraksi dengan pengguna. Bagaimana cara memotong UIImage sepenuhnya ke gambar lain, bukan topeng.

@IBOutlet weak var imageView: UIImageView!

override func viewDidLoad() {
    super.viewDidLoad()
    let imageMask = UIImageView()

    imageMask.image = //image to mask

    imageMask.frame = photoImageView.bounds
    imageView.mask = imageMask
}

masukkan deskripsi gambar di sini masukkan deskripsi gambar di sini


person Cristian    schedule 20.11.2018    source sumber
comment
stackoverflow.com/questions/32041420/ Saya rasa pertanyaan ini serupa   -  person Ruban4Axis    schedule 20.11.2018


Jawaban (1)


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

person Stephan Schlecht    schedule 02.12.2018
comment
Terima kasih, ini menjawab pertanyaan saya dengan tepat - person Cristian; 02.12.2018