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 | 31 |
Tags
- SWIFT
- 리팩토링
- RxCocoa
- Xcode
- tableView
- 리펙토링
- UICollectionView
- 클린 코드
- Observable
- Clean Code
- map
- swiftUI
- uitableview
- clean architecture
- uiscrollview
- 스위프트
- HIG
- 애니메이션
- ios
- 리펙터링
- Refactoring
- UITextView
- Protocol
- ribs
- collectionview
- Human interface guide
- combine
- rxswift
- MVVM
- swift documentation
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[iOS - swift] 3. CALayer 마스킹 활용 - 뷰 합치는 방법 본문
1. CALayer 마스킹 활용 - 마스킹하는 기본 방법 (mask, .evenOdd)
2. CALayer 마스킹 활용 - 특정 뷰 음영 효과 주는 방법
3. CALayer 마스킹 활용 - 뷰 합치는 방법 <
뷰 합치기 아이디어
- 이미지 뷰 두 개를 준비
- 이미지 뷰 두 개를 width와 위치를 동일하게 constraint하고난 후 각각 path, mask를 사용하여 자르기
구현
* 예제에 나온 코드는 코드로 UI 작성의 편의를 위해 SnapKit 사용
- 구현은 사용하는쪽에서 이미지 두 개와, ratio를 주입하여 뷰를 생성하면 자동으로 이미지 두 개가 나누어지도록 구현
- 아래에서 SlantView 구현
* slant: 경사진
- 아래에서 SlantView 구현
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let slantView = SlantView(firstImage: .init(named: "1"), secondImage: .init(named: "2"), ratio: 0.9)
view.addSubview(slantView)
slantView.snp.makeConstraints {
$0.size.equalTo(350)
$0.center.equalToSuperview()
}
}
}
- ratio 값의 의미
- SlantView 선언
final class SlantView: UIView {
private let ratio: Double
private let firstImageView: UIImageView
private let secondImageView: UIImageView
}
- 생성자
- setUp()은 아래에서 계속 구현
init(firstImage: UIImage?, secondImage: UIImage?, ratio: Double) {
self.ratio = ratio
self.firstImageView = UIImageView(image: firstImage)
self.secondImageView = UIImageView(image: secondImage)
super.init(frame: .zero)
setUp()
}
required init?(coder: NSCoder) {
fatalError()
}
- 이미지뷰의 contentMode과 layout 설정
private func setUp() {
backgroundColor = .clear
firstImageView.contentMode = .scaleAspectFill
secondImageView.contentMode = .scaleAspectFill
addSubview(firstImageView)
addSubview(secondImageView)
firstImageView.snp.makeConstraints {
$0.top.leading.bottom.equalToSuperview()
$0.width.equalToSuperview()
}
secondImageView.snp.makeConstraints {
$0.top.trailing.bottom.equalToSuperview()
$0.width.equalToSuperview()
}
}
- 이미지뷰 마스킹
- 마스킹은 이미지뷰의 bounds가 정해졌을때 이 값을 사용하여 마스킹할 수 있으므로 layoutSubviews에서 호출
override func layoutSubviews() {
super.layoutSubviews()
mask()
}
- mask() 구현
- mask의 기본 3단계 (path로 남길 부분을 그리기 -> shapeLayer에 path 대입 -> layer.mask에 대입)
- 핵심 부분은 path를 그리는 것이고 이 부분의 코드가 길기 때문에 따로 메소드로 빼서 구현
private func mask() {
// 1. path 인스턴스로 경로 정보 획득
let firstPath = getFirstImagePath()
let secondPath = getSecondImagePath()
// 2. shapeLayer.path에 위 path 인스턴스 대입
let firstShapeLayer = CAShapeLayer()
firstShapeLayer.path = firstPath.cgPath
let secondShapeLayer = CAShapeLayer()
secondShapeLayer.path = secondPath.cgPath
// 3. layer.mask에 shapeLayer를 대입
firstImageView.layer.mask = firstShapeLayer
secondImageView.layer.mask = secondShapeLayer
}
- path 그리기
- 좌측 상단에서부터 시계방향으로 그리기
private func getFirstImagePath() -> UIBezierPath {
let path = UIBezierPath()
let bs = firstImageView.bounds
path.move(to: bs.origin)
path.addLine(to: .init(x: bs.maxX * ratio, y: bs.minY))
path.addLine(to: .init(x: bs.minX + bs.width * (1 - ratio), y: bs.maxY))
path.addLine(to: .init(x: bs.minX, y: bs.maxY))
path.close()
return path
}
private func getSecondImagePath() -> UIBezierPath {
let path = UIBezierPath()
let bs = secondImageView.bounds
path.move(to: .init(x: bs.minX + bs.width * ratio, y: bs.minY))
path.addLine(to: .init(x: bs.maxX, y: bs.minY))
path.addLine(to: .init(x: bs.maxX, y: bs.maxY))
path.addLine(to: .init(x: bs.minX + bs.width * (1 - ratio), y: bs.maxY))
path.close()
return path
}
(완료)
'iOS 응용 (swift)' 카테고리의 다른 글
[iOS - swift] Push Notification 간단 테스트 방법 (시뮬레이터) (0) | 2023.02.16 |
---|---|
[iOS - swift] 1. FlexLayout과 PinLayout 사용 방법 - UIStackView 개선, 속도 향상, 기능 추가, 선언형 (0) | 2023.02.15 |
[iOS - swift] 2. CALayer 마스킹 활용 - 특정 뷰 음영 효과 주는 방법 (0) | 2023.02.13 |
[iOS - swift] 1. CALayer 마스킹 활용 - 마스킹하는 방법 (layer.mask, .evenOdd) (0) | 2023.02.12 |
[iOS - swift] Mirror 개념, Mirror(reflecting:) (0) | 2023.02.11 |
Comments