Swift에서 스프링처럼 바운스하는 메뉴를 만들어 보았습니다.

11052 단어 iOSSwiftanimation
Skype의 iOS 앱에서 보는 바운드하는 애니메이션을 구현해 보았다.
그 요점을 정리해 둔다.

데모



htps : // 기주 b. 코 m/y타 k↑/호쿠사이


구현 방법



CADisplayLink



애니메이션에는 CADisplayLink를 사용했다.
디스플레이가 업데이트되는 시점에서 함수가 실행되므로,
NSTimer보다 애니메이션이 더 적합합니다.

UIBezierPath



파도 같은 애니메이션을 만들기 위해 베지어 곡선을 사용합니다.
구체적으로는 UIBezierPath로 매 프레임마다 CALayer를 그립니다.
// レイヤーの開始点に移動
UIBezierPath().moveToPoint(開始点)

// 現在の点からベジェ曲線を描いて次の点へ移動
UIBezierPath().addQuadCurveToPoint(次の点,
        controlPoint:曲率を作るための制御点)

// 現在の点から開始点までのパスを閉じる
UIBezierPath().closePath()

베지어 곡선에 대해서는, 이것을 보면 어쩐지 이미지 할 수 있을 것이다.
ベジェ曲線
출처 : 시 g부 s. 인포

해당 소스 코드


// アニメーション開始時に呼ばれる
func positionAnimationWillStart() {
    // displayLinkでループ開始
    if displayLink == nil {
        displayLink = CADisplayLink(target: self, selector: "tick:")
        displayLink!.addToRunLoop(NSRunLoop.mainRunLoop(), forMode: NSDefaultRunLoopMode)
    }
}

// アニメーションの関数
func updatePath() {
    // 四角形の幅と高さを取得
    let width  = CGRectGetWidth(shapeLayer.bounds)
    let height = CGRectGetHeight(shapeLayer.bounds)

    // パスを描く
    // bendableOffsetが肝で、画面からせり出してくる距離に応じて大きさを変化させ、
    // メニュー上部の波を作る。
    let path = UIBezierPath()
    path.moveToPoint(CGPoint(x: 0, y: 0))
    path.addQuadCurveToPoint(CGPoint(x: width, y: 0),
        controlPoint:CGPoint(x: width * 0.5, y: 0 + bendableOffset.vertical))
    path.addQuadCurveToPoint(CGPoint(x: width, y: height + 100.0),
        controlPoint:CGPoint(x: width + bendableOffset.horizontal, y: height * 0.5))
    path.addQuadCurveToPoint(CGPoint(x: 0, y: height + 100.0),
        controlPoint: CGPoint(x: width * 0.5, y: height + 100.0))
    path.addQuadCurveToPoint(CGPoint(x: 0, y: 0),
        controlPoint: CGPoint(x: bendableOffset.horizontal, y: height * 0.5))
    path.closePath()

    shapeLayer.path = path.CGPath
}

func tick(displayLink: CADisplayLink) {
    if let presentationLayer = layer.presentationLayer() as? CALayer {
        // メニューの位置によってoffsetの大きさを変化させる。
        var verticalOffset = self.layer.frame.origin.y - presentationLayer.frame.origin.y

        bendableOffset = UIOffset(
            horizontal: 0.0,
            vertical: verticalOffset
        )
        // アニメーション用の関数を呼ぶ
        updatePath()

        // offsetが0になったタイミングでループを終了
        if verticalOffset == 0 {
            self.displayLink!.invalidate()
            self.displayLink = nil
        }
    }
}

도서관



모처럼이므로 라이브러리화해 github에 공개했다.
cocoapods, Carthage 어느 쪽에도 대응하고 있다.
htps : // 기주 b. 코 m/y타 k↑/호쿠사이

사용법은 간단.
클로저에서도 셀렉터에도 대응하고 있기 때문에 여러가지 용도에 사용할 수 있을 것.
let hokusai = Hokusai()

// クロージャーでコールバックを定義する
hokusai.addButton("Button 1") {
    println("Rikyu")
}

// セレクターでもコールバックを定義できる
hokusai.addButton("Button 2", target: self, selector: Selector("button2Pressed"))

// メニューを出す
hokusai.show()

func button2Pressed() {
    println("Oribe")
}

좋은 웹페이지 즐겨찾기