UIBezierPath — kelas dari UIKit yang mengenkapsulasi jalur vektor untuk grafis 2D di iOS. Ini menggabungkan deskripsi geometris kontur dengan kemampuan menggambar, memungkinkan pembuatan garis, kurva Bézier, busur, dan persegi panjang. Tidak seperti CGPath, UIBezierPath berisi metode menggambar sendiri langsung dalam konteks grafis saat ini. Menurut Apple Developer Documentation, 2026, UIBezierPath mendukung semua operasi standar Quartz 2D dalam bungkus berorientasi objek.
Poin Utama
UIBezierPath — kelas dari framework UIKit, mewarisi NSObject dan mengimplementasikan NSCopying, NSSecureCoding. Ini menyediakan API Objective-C/Swift tingkat tinggi untuk membangun dan menggambar kontur vektor. Secara internal, UIBezierPath menyimpan referensi ke CGPathRef — objek Core Graphics, tetapi menambahkan metode yang nyaman untuk menggambar, mengubah geometri, dan mengelola gaya.
Keuntungan utama UIBezierPath dibandingkan penggunaan langsung CGPath adalah metode menggambar bawaan. Memanggil fill() atau stroke() pada instance UIBezierPath secara otomatis mengonfigurasi konteks dan menggambar jalur. Kelas ini juga mendukung properti lineWidth, lineCapStyle, lineJoinStyle, miterLimit dan flatness, yang memungkinkan pengelolaan tampilan tanpa objek terpisah untuk penyimpanan gaya.
UIBezierPath digunakan di sebagian besar aplikasi iOS untuk menggambar kustom di dalam UIView: dari ikon sederhana hingga grafik animasi kompleks. Metode draw(_:) dari kelas UIView adalah tempat utama di mana pengembang membuat dan menggambar UIBezierPath. Kelas ini sepenuhnya kompatibel dengan Core Animation dan dapat digunakan untuk animasi jalur melalui CAShapeLayer dan CABasicAnimation.
Metode move(to:) memindahkan titik awal jalur ke koordinat yang diberikan tanpa menggambar. Ini adalah panggilan wajib sebelum membangun segmen apa pun. addLine(to:) menambahkan segmen garis lurus dari posisi saat ini ke titik yang ditentukan. Untuk menutup kontur, digunakan metode close(), yang menarik garis dari titik terakhir ke titik pertama dari move(to:) terakhir.
UIBezierPath menyediakan beberapa penginisialisasi yang nyaman untuk bentuk jadi. init(rect:) membuat persegi panjang, init(roundedRect:cornerRadius:) — persegi panjang dengan sudut membulat. Parameter UIRectCorner memungkinkan pembulatan hanya sudut yang dipilih, misalnya topLeft dan bottomRight, membiarkan yang lain tetap lurus. Ini banyak digunakan untuk membuat tombol dan kartu kustom.
init(ovalIn:) membuat elips yang tertulis dalam persegi panjang yang diberikan. Jika persegi panjang adalah bujur sangkar, elips berubah menjadi lingkaran. init(roundedRect:byRoundingCorners:cornerRadii:) — varian paling fleksibel, memungkinkan pengaturan radius berbeda untuk setiap sudut. Penginisialisasi ini muncul di iOS 6 dan tetap menjadi standar untuk pembuatan wadah membulat.
let path = UIBezierPath()
path.move(to: CGPoint(x: 50, y: 50))
path.addLine(to: CGPoint(x: 200, y: 50))
path.addLine(to: CGPoint(x: 200, y: 150))
path.addLine(to: CGPoint(x: 125, y: 200))
path.addLine(to: CGPoint(x: 50, y: 150))
path.close()
addQuadCurve(to:controlPoint:) menambahkan kurva Bézier kuadrat dengan satu titik kontrol. Jenis kurva ini digunakan untuk lengkungan halus sederhana ketika diperlukan minimalisasi jumlah perhitungan. Kurva kuadrat selalu merupakan parabola dan dijamin berada di dalam segitiga yang dibentuk oleh titik awal, kontrol, dan akhir.
addCurve(to:controlPoint1:controlPoint2:) menambahkan kurva Bézier kubik dengan dua titik kontrol. Kurva kubik digunakan di semua editor vektor modern dan font TrueType. Dua titik kontrol memberikan lebih banyak derajat kebebasan untuk kontrol bentuk kurva yang presisi. Metode ini direkomendasikan untuk membangun kontur organik dan kompleks.
Saat membangun kurva, penting untuk mematuhi prinsip kontinuitas — kehalusan kurva di titik sambungan segmen. Untuk kontinuitas C1 (garis singgung), titik kontrol kurva berikutnya harus berada pada garis lurus yang sama dengan titik kontrol kurva sebelumnya. Untuk kontinuitas C2 (kelengkungan), diperlukan penyesuaian yang lebih kompleks, yang secara otomatis dijamin di CAShapeLayer saat animasi antara dua UIBezierPath dengan jumlah titik kontrol yang sama.
| Metode | Tipe | Titik kontrol | Derajat |
|---|---|---|---|
| addQuadCurve | Bézier kuadrat | 1 | 2 |
| addCurve | Bézier kubik | 2 | 3 |
| addArc | Busur | — | — |
addArc(withCenter:radius:startAngle:endAngle:clockwise:) menambahkan busur lingkaran dengan parameter yang diberikan. Sudut ditentukan dalam radian relatif terhadap pusat lingkaran. Sudut nol sesuai dengan arah ke kanan (jam 3 pada pelat jam). Parameter clockwise menentukan arah: true — searah jarum jam, false — berlawanan. Busur sangat penting untuk diagram lingkaran, speedometer, dan cincin progres interaktif.
Untuk lingkaran penuh, startAngle = 0 dan endAngle = .pi * 2 sudah cukup. Untuk membuat sektor (sebagai bagian dari diagram lingkaran) gunakan addArc diikuti dengan addLine(to:) ke pusat dan close(). UIBezierPath tidak memiliki metode addCircle bawaan — lingkaran dibuat melalui init(ovalIn:) dengan persegi panjang bujur sangkar atau melalui addArc dengan sudut penuh.
Metode addArc(withCenter:radius:startAngle:endAngle:clockwise:) secara otomatis melakukan move(to:) ke titik awal busur jika posisi saat ini tidak cocok dengannya. Jika posisi saat ini berbeda, garis lurus ditarik antara posisi tersebut dan awal busur. Perilaku ini berbeda dari bekerja dengan Core Graphics, di mana move(to:) eksplisit diperlukan sebelum setiap kontur baru.
let center = CGPoint(x: 150, y: 150)
let slice = UIBezierPath()
slice.move(to: center)
slice.addArc(
withCenter: center,
radius: 100,
startAngle: 0,
endAngle: .pi * 0.75,
clockwise: true
)
slice.close()
fill() mengisi area dalam jalur dengan warna fillColor saat ini atau warna yang diatur dalam konteks grafis melalui setFill(). Untuk jalur dengan persilangan sendiri, aturan pengisian ditentukan oleh properti usesEvenOddFillRule. Jika true, aturan even-odd diterapkan: sebuah titik dianggap di dalam bentuk jika sinar darinya memotong kontur sebanyak ganjil.
stroke() menggambar kontur jalur dengan pengaturan saat ini lineWidth, lineCapStyle dan lineJoinStyle. lineCapStyle menentukan bentuk ujung segmen terbuka: .butt (potongan lurus), .round (setengah lingkaran), .square (persegi dengan tonjolan). lineJoinStyle menentukan bentuk sudut sambungan: .miter (tajam), .round (membulat), .bevel (terpotong).
Untuk garis putus-putus, digunakan properti setLineDash(_:count:phase:). Ini menerima array panjang garis putus dan spasi bergantian, jumlah elemen, dan fase awal. Visualisasi garis putus-putus dilakukan pada tahap rasterisasi jalur — pola kompleks tidak meningkatkan kompleksitas geometris kontur. CAShapeLayer mendukung animasi properti strokeEnd untuk efek “menggambar” garis dari awal hingga akhir.
override func draw(_ rect: CGRect) {
let path = UIBezierPath(ovalIn: CGRect(x: 50, y: 50, width: 200, height: 200))
UIColor.blue.setFill()
UIColor.black.setStroke()
path.lineWidth = 4
path.fill()
path.stroke()
}
Mari buat indikator kemajuan kustom berbentuk cincin menggunakan UIBezierPath. Cincin dibangun dari dua busur dengan radius yang sama tetapi warna garis tepi berbeda. Busur pertama — lingkaran penuh warna abu-abu (latar belakang), kedua — segmen yang menampilkan kemajuan. Untuk animasi digunakan CAShapeLayer dan CABasicAnimation.
class RingView: UIView {
private let progressLayer = CAShapeLayer()
override func layoutSubviews() {
super.layoutSubviews()
let center = CGPoint(x: bounds.midX, y: bounds.midY)
let radius = bounds.width * 0.4
let lineWidth: CGFloat = 12
let backgroundRing = UIBezierPath()
backgroundRing.addArc(withCenter: center, radius: radius,
startAngle: -.pi / 2, endAngle: .pi * 1.5, clockwise: true)
progressLayer.path = backgroundRing.cgPath
progressLayer.strokeColor = UIColor.systemBlue.cgColor
progressLayer.lineWidth = lineWidth
progressLayer.lineCap = .round
progressLayer.fillColor = UIColor.clear.cgColor
progressLayer.strokeEnd = 0
layer.addSublayer(progressLayer)
}
func animateProgress(to value: CGFloat) {
CABasicAnimation(keyPath: "strokeEnd").apply {
$0.toValue = value
$0.duration = 1.5
$0.timingFunction = CAMediaTimingFunction(name: .easeOut)
progressLayer.add($0, forKey: nil)
}
progressLayer.strokeEnd = value
}
}
Dalam contoh ini UIBezierPath digunakan untuk membuat kontur melingkar, yang kemudian diteruskan ke CAShapeLayer melalui properti cgPath. Animasi strokeEnd dari 0 hingga 1 memvisualisasikan pengisian cincin. Pendekatan ini digunakan dalam indikator pemuatan, pelacak kebugaran, dan widget kemajuan. Metode layoutSubviews menjamin pembangunan ulang jalur saat ukuran View berubah.
lineCap = .round menambahkan ujung membulat pada busur, memberikan indikator tampilan yang lebih rapi. Properti strokeEnd adalah properti CAShapeLayer yang dapat dianimasi yang tidak memerlukan penggambaran ulang seluruh kontur di setiap bingkai. Animasi sepenuhnya dilakukan di GPU melalui Core Animation, memastikan 60 FPS tanpa membebani CPU.
Pertanyaan yang Sering Diajukan
UIBezierPath — bungkus berorientasi objek dari CGPath yang berisi metode fill() dan stroke() bawaan. CGPath adalah objek C Core Graphics yang tidak dapat dimodifikasi dan memerlukan penggambaran eksplisit melalui CGContext. UIBezierPath lebih nyaman untuk UIKit, CGPath lebih efisien untuk penggunaan ulang.
Gunakan init(roundedRect:byRoundingCorners:cornerRadii:) dengan parameter .topLeft dan .topRight untuk roundedRect. Ini adalah satu-satunya metode UIBezierPath yang memungkinkan pembulatan sudut secara selektif tanpa membuat jalur majemuk yang kompleks.
Properti cgPath mengembalikan CGPathRef yang tidak dapat diubah yang dapat diteruskan ke CAShapeLayer atau digunakan dengan warna dan ketebalan berbeda. Modifikasi UIBezierPath (memindahkan titik) tidak memengaruhi cgPath yang diperoleh sebelumnya hingga pembaruan eksplisit.
Periksa usesEvenOddFillRule — jika kontur memiliki persilangan sendiri, aturan even-odd dapat meninggalkan area tidak terisi. Atur usesEvenOddFillRule = false untuk aturan pengisian non-zero winding standar.
Gunakan CABasicAnimation dengan jalur kunci “path” pada CAShapeLayer. Kedua keadaan jalur harus memiliki jumlah segmen dan titik kontrol yang sama — jika tidak, animasi akan tersendat atau tidak berfungsi.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga