Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- uitableview
- MVVM
- Human interface guide
- Refactoring
- rxswift
- Clean Code
- UICollectionView
- 클린 코드
- tableView
- 애니메이션
- ios
- clean architecture
- swift documentation
- HIG
- map
- combine
- SWIFT
- 리팩토링
- UITextView
- 스위프트
- uiscrollview
- 리펙토링
- Protocol
- 리펙터링
- RxCocoa
- Observable
- collectionview
- ribs
- Xcode
- swiftUI
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - SwiftUI] Shape, InsettableShape 사용 방법(Custom Shape, inset(by:)) 본문
iOS 기본 (SwiftUI)
[iOS - SwiftUI] Shape, InsettableShape 사용 방법(Custom Shape, inset(by:))
jake-kim 2022. 10. 15. 23:08Shape
- 2D 모양의 뷰를 의미하는 프로토콜 (Circle, Capsule, Ellipse, ... 등)
- Shape 프로토콜 형태
- path(in:)->Path: shape의 형태를 Path로 리턴
- role: 모양을 채우는 스타일을 정의하며, 결합 모양(composite shape)과 같은 것을 만들때 이 프로퍼티를 재정의하여 사용
- default implementation이 존재 - ShapeRole.fill이 있고 stroke와 separator가 있는 타입
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
public protocol Shape : Animatable, View {
func path(in rect: CGRect) -> Path
static var role: ShapeRole { get }
}
ex) Shape 프로토콜을 준수하는 대표적인 Shape - Capsule()
@available(iOS 13.0, macOS 10.15, tvOS 13.0, watchOS 6.0, *)
@frozen public struct Capsule : Shape {
public var style: RoundedCornerStyle
@inlinable public init(style: RoundedCornerStyle = .circular)
public func path(in r: CGRect) -> Path
public typealias AnimatableData = EmptyAnimatableData
public typealias Body
}
커스텀 Shape 만들기 (Circle)
- Shape를 준수하고, path(in:) -> Path 메소드 구현
struct ContentView: View {
var body: some View {
MyCircle()
.frame(width: 120, height: 120)
.foregroundColor(.blue)
}
}
struct MyCircle: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
path.addArc(
center: CGPoint(x: rect.midX, y: rect.midY), // 중심
radius: rect.width / 2, // 반지름
startAngle: Angle.degrees(180), // 시작 위치
endAngle: Angle.degrees(-180), // 끝 위치
clockwise: true // true - 시계 방향, false - 반시계 방향
)
return path
}
}
InsettableShape
- 사용하는쪽에서 inset(by:)를 사용하여 frame에 대해서 inset값을 줄 수 있는 형태
- MyCicle에 InsettableShape를 준수하고, inset(by:)->InsettableShape 메소드를 정의
struct MyCircle: Shape, InsettableShape {
func path(in rect: CGRect) -> Path {
...
}
func inset(by amount: CGFloat) -> some InsettableShape {
// TODO
}
}
- inset(by:) 구현부에서는 현재 self 인스턴스를 복사한 후 처리하는 방식
- insetValue라는 프로퍼티 선언
- path내부에서 초기화할때 insetValue를 이용
- inset(by:) 메소드 내부에서 insetValue를 적용
struct MyCircle: Shape, InsettableShape {
private var insetValue = 0.0 // <-
func path(in rect: CGRect) -> Path {
var path = Path()
path.addArc(
...
radius: rect.width / 2 - insetValue, // <-
...
)
return path
}
func inset(by amount: CGFloat) -> some InsettableShape {
var myCircle = self
myCircle.insetValue = amount // <-
return myCircle
}
}
- 사용하는쪽
struct ContentView: View {
var body: some View {
MyCircle()
.inset(by: 20) // <-
.frame(width: 120, height: 120)
.foregroundColor(.blue)
}
}
* 전체 코드: https://github.com/JK0369/ExShape-SwiftUI
* 참고
https://developer.apple.com/documentation/swiftui/insettableshape
https://developer.apple.com/documentation/swiftui/shaperole/fill
'iOS 기본 (SwiftUI)' 카테고리의 다른 글
Comments