TimelineView 소개

13105 단어 swiftuiswift
WWDC21에서 Apple은 상태 변수에 의존하지 않고 일정에 따라 자체적으로 업데이트되는 새로운 SwiftUI 보기인 TimelineView를 소개했습니다.
일부 시나리오에서는 유용할 수 있습니다. 예를 들어 X초마다 뷰를 새로고침하거나 주어진 간격으로 새 프레임을 제공하는 것을 애니메이션으로 만들고 싶거나 앱에 시계만 표시하려는 경우에도 유용할 수 있습니다. .

예를 들어 하루 중 시간을 표시하고 매분 변경되는 보기를 살펴보겠습니다.

TimelineView(.everyMinute) { context in
    Text(context.date.formatted())
}


이것은 정말 간단한 예입니다. TimelineView는 매분 실행되는 everyMinute라는 특정 TimelineScheduler로 인스턴스화됩니다.
즉, TimelineView 내부의 텍스트가 매분 평가되고 클로저에 전달된 컨텍스트 변수에 날짜가 포함되므로 현재 시간을 표시할 수 있습니다.
참고 저는 형식이 지정된 수정자를 사용했습니다. 이것은 올해의 또 다른 멋진 추가 기능이며 다른 예를 보게 될 것입니다.

정기 타임라인 일정



시간을 표시하고 싶지만 업데이트가 매초이면 어떻게 됩니까?
periodic(from:by:)를 통해 인스턴스화된 PeriodicTimelineSchedule을 사용하여 시작 날짜를 설정하고(과거인 경우 보기가 즉시 업데이트됨) 보기를 업데이트할 빈도를 정의할 수 있습니다.

TimelineView(.periodic(from: .now, by: 1.0)) { context in
    Text(context.date.formatted(date: .omitted, time: .standard))
}


이 예에서 보기는 1초마다 업데이트됩니다. 날짜 형식을 다르게 지정했습니다. 이번에는 날짜를 생략하여 오후 4시 30분 25초와 같이 인쇄합니다.

명시적 타임라인 일정



더 많은 제어가 필요한 일정의 또 다른 팁은 ExplicitTimelineSchedule입니다. 날짜 배열을 제공할 수 있으며 TimelineView는 지정된 시간에만 업데이트됩니다.

TimelineView(.explicit(getDates())) { context in
    Text(context.date.formatted(date: .omitted, time: .standard))
}

private func getDates() -> [Date] {
    let date = Date()
    return [date,
            date.addingTimeInterval(2.0),
            date.addingTimeInterval(4.0),
            date.addingTimeInterval(6.0)]
}


아날로그 시계 만들기



TimelineView의 도움으로 SwiftUI에서 재미를 느끼고 아날로그 시계를 만들어 봅시다. GitHub에서 코드를 찾을 수 있습니다.



방금 본 것처럼 TimelineView는 일정에 따라 뷰를 업데이트할 수 있는 편리한 방법을 제공합니다. 시간이 지남에 따라 손이 움직여야 합니다. 초침을 구현하려면 매초 콘텐츠를 새로 고치는 스케줄러가 필요하므로 그것부터 시작하겠습니다.

var body: some View {
    TimelineView(.periodic(from: Date(), by: 1.0)) { context in
        VStack {
            Text(context.date.formatted(date: .omitted, time: .standard))
            ZStack {
                clockHands(date: context.date)
            }
        }
        .frame(width: 300, height: 300)
    }
}


이 TimelineView는 매초마다 새로 고쳐집니다. 이제 손을 올바르게 배치하는 것이 중요합니다.

@ViewBuilder
private func clockHands(date: Date) -> some View {
    ClockHand(handScale: 0.5)
        .stroke(lineWidth: 5.0)
        .rotationEffect(angle(fromDate: date, type: .hour))
    ClockHand(handScale: 0.6)
        .stroke(lineWidth: 3.0)
        .rotationEffect(angle(fromDate: date, type: .minute))
    ClockHand(handScale: 0.8)
        .stroke(lineWidth: 1.0)
        .rotationEffect(angle(fromDate: date, type: .second))
}


시침이 분보다 짧고 초침이 더 얇고 길기 때문에 각 ClockHand는 하나의 모양이며 선 너비와 길이가 다릅니다.
우리가 해야 할 일은 값에 따라 각 손을 회전시키는 것입니다.

private func angle(fromDate: Date, type: ClockHandType) -> Angle {
    var timeDegree = 0.0
    let calendar = Calendar.current

    switch type {
    case .hour:
        // we have 12 hours so we need to multiply by 5 to have a scale of 60
        timeDegree = CGFloat(calendar.component(.hour, from: fromDate)) * 5
    case .minute:
        timeDegree = CGFloat(calendar.component(.minute, from: fromDate))
    case .second:
        timeDegree = CGFloat(calendar.component(.second, from: fromDate))
    }
    return Angle(degrees: timeDegree * 360.0 / 60.0)
}


1분은 60초, 1시간은 60분이 있지만 시계는 12시간이므로 시간에 5를 곱해야 작동합니다. return 문에서 볼 수 있듯이 60으로 나누기 때문입니다.

그게 다야, 몇 줄의 코드로 간단하지만 작동하는 아날로그 시계를 만들 수 있습니다.
행복한 코딩 🙂

Original post

좋은 웹페이지 즐겨찾기