탐색 기반 응용 프로그램이 있고 푸시 및 팝 애니메이션의 애니메이션을 변경하고 싶습니다. 어떻게해야합니까?
2018 수정
이 질문에 대한 많은 답변이 있었으며 지금은 꽤 오래 걸렸습니다. 지금 가장 관련성이 있다고 생각되는 것에 대한 답변을 다시 선택했습니다. 다르게 생각하는 사람이 있으면 의견을 남겨주세요.
답변
탐색 기반 앱에서 푸시 및 팝 애니메이션을 변경하는 방법 …
2019 년에는 “최종 답변!”
전문:
iOS 개발에 익숙하지 않다고 가정 해보십시오. 혼란스럽게도 Apple은 쉽게 사용할 수있는 두 가지 전환을 제공합니다. “crossfade”와 “flip”이 있습니다.
그러나 “crossfade”와 “flip”은 쓸모가 없습니다. 그들은 결코 사용되지 않습니다. 애플이 왜이 두 가지 쓸모없는 전환을 제공했는지는 아무도 모른다!
그래서:
“슬라이드”와 같이 일반적인 일반적인 전환 을 수행하려고한다고 가정합니다 . 이 경우 엄청난 양의 작업을 수행해야합니다! .
이 작업은이 게시물에 설명되어 있습니다.
반복하기 만하면됩니다.
놀랍게도 : iOS를 사용하면 가장 단순하고 일반적인 일상 전환 (예 : 일반 슬라이드)을 원한다면 전체 사용자 정의 전환 을 구현하는 모든 작업 이 필요합니다 .
방법은 다음과 같습니다.
1. 당신은 관례가 필요합니다 UIViewControllerAnimatedTransitioning
-
당신은 자신의 부울이 필요합니다
popStyle
. (튀어 나오거나 터지는가?) -
transitionDuration
(사소한) 주요 전화를 포함해야합니다 .animateTransition
-
실제로 inside에 대해 두 가지 다른 루틴을 작성 해야합니다
animateTransition
. 하나는 푸시 용이고 다른 하나는 팝용입니다. 아마 그 이름animatePush
과animatePop
. 내부 에서 두 루틴으로animateTransition
분기하십시오.popStyle
-
아래 예제는 간단한 이동 / 이동을 수행합니다.
-
당신
animatePush
과animatePop
일상에서. 당신은 해야한다 은 “보기”및 “보기에”를 얻는다. (이를 수행하는 방법은 코드 예제에 나와 있습니다.) -
새로운 “to”보기 를 사용해야합니다
addSubview
. -
그리고 당신 은
completeTransition
애니메이션의 끝에서 전화 해야합니다
그래서 ..
class SimpleOver: NSObject, UIViewControllerAnimatedTransitioning {
var popStyle: Bool = false
func transitionDuration(
using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.20
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
if popStyle {
animatePop(using: transitionContext)
return
}
let fz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
let tz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
let f = transitionContext.finalFrame(for: tz)
let fOff = f.offsetBy(dx: f.width, dy: 55)
tz.view.frame = fOff
transitionContext.containerView.insertSubview(tz.view, aboveSubview: fz.view)
UIView.animate(
withDuration: transitionDuration(using: transitionContext),
animations: {
tz.view.frame = f
}, completion: {_ in
transitionContext.completeTransition(true)
})
}
func animatePop(using transitionContext: UIViewControllerContextTransitioning) {
let fz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)!
let tz = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)!
let f = transitionContext.initialFrame(for: fz)
let fOffPop = f.offsetBy(dx: f.width, dy: 55)
transitionContext.containerView.insertSubview(tz.view, belowSubview: fz.view)
UIView.animate(
withDuration: transitionDuration(using: transitionContext),
animations: {
fz.view.frame = fOffPop
}, completion: {_ in
transitionContext.completeTransition(true)
})
}
}
그리고 …
2. 뷰 컨트롤러에서 사용하십시오.
참고 : 이상하게도 “첫 번째”보기 컨트롤러 에서만이 작업을 수행해야합니다 . (아래에있는 것)
당신이 상단에 팝업 하나 , 아무것도 하지 마십시오 . 쉬운.
수업은 …
class SomeScreen: UIViewController {
}
된다 …
class FrontScreen: UIViewController,
UIViewControllerTransitioningDelegate, UINavigationControllerDelegate {
let simpleOver = SimpleOver()
override func viewDidLoad() {
super.viewDidLoad()
navigationController?.delegate = self
}
func navigationController(
_ navigationController: UINavigationController,
animationControllerFor operation: UINavigationControllerOperation,
from fromVC: UIViewController,
to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
simpleOver.popStyle = (operation == .pop)
return simpleOver
}
}
그게 다야.
정상적으로 정상적으로 밀고 터지십시오. 밀어 …
let n = UIStoryboard(name: "nextScreenStoryboardName", bundle: nil)
.instantiateViewController(withIdentifier: "nextScreenStoryboardID")
as! NextScreen
navigationController?.pushViewController(n, animated: true)
다음 화면에서 원하는 경우 팝업을 표시 할 수 있습니다.
class NextScreen: TotallyOrdinaryUIViewController {
@IBAction func userClickedBackOrDismissOrSomethingLikeThat() {
navigationController?.popViewController(animated: true)
}
}
휴
3.이 페이지에서 AnimatedTransitioning을 재정의하는 방법을 설명하는 다른 답변도 즐기십시오
AnimatedTransitioning
요즘 iOS 앱 사용 방법에 대한 자세한 내용은 @AlanZeino 및 @elias 답변으로 스크롤하십시오 !
답변
나는 다음을했고 잘 작동합니다 .. 간단하고 이해하기 쉽습니다 ..
CATransition* transition = [CATransition animation];
transition.duration = 0.5;
transition.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
transition.type = kCATransitionFade; //kCATransitionMoveIn; //, kCATransitionPush, kCATransitionReveal, kCATransitionFade
//transition.subtype = kCATransitionFromTop; //kCATransitionFromLeft, kCATransitionFromRight, kCATransitionFromTop, kCATransitionFromBottom
[self.navigationController.view.layer addAnimation:transition forKey:nil];
[[self navigationController] popViewControllerAnimated:NO];
그리고 똑같은 것도 ..
스위프트 3.0 버전 :
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionFade
self.navigationController?.view.layer.add(transition, forKey: nil)
_ = self.navigationController?.popToRootViewController(animated: false)
답변
이것이 내가 항상이 작업을 완료 한 방법입니다.
푸시의 경우 :
MainView *nextView=[[MainView alloc] init];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[self.navigationController pushViewController:nextView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[nextView release];
팝의 경우 :
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationDuration:0.75];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
[UIView commitAnimations];
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDelay:0.375];
[self.navigationController popViewControllerAnimated:NO];
[UIView commitAnimations];
나는 여전히 이것으로부터 많은 피드백을 얻으므로 어쨌든 애니메이션을 수행하는 Apple 권장 방법 인 애니메이션 블록을 사용하도록 업데이트 할 것입니다.
푸시의 경우 :
MainView *nextView = [[MainView alloc] init];
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[self.navigationController pushViewController:nextView animated:NO];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromRight forView:self.navigationController.view cache:NO];
}];
팝의 경우 :
[UIView animateWithDuration:0.75
animations:^{
[UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
[UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft forView:self.navigationController.view cache:NO];
}];
[self.navigationController popViewControllerAnimated:NO];
답변
푸시
CATransition *transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionFade;
//transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController pushViewController:ViewControllerYouWantToPush animated:NO];
팝
CATransition *transition = [CATransition animation];
transition.duration = 0.3;
transition.type = kCATransitionFade;
//transition.subtype = kCATransitionFromTop;
[self.navigationController.view.layer addAnimation:transition forKey:kCATransition];
[self.navigationController popViewControllerAnimated:NO];
답변
@Magnus는 Swift (2.0)에 대해서만 대답합니다.
let transition = CATransition()
transition.duration = 0.5
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = kCATransitionPush
transition.subtype = kCATransitionFromTop
self.navigationController!.view.layer.addAnimation(transition, forKey: nil)
let writeView : WriteViewController = self.storyboard?.instantiateViewControllerWithIdentifier("WriteView") as! WriteViewController
self.navigationController?.pushViewController(writeView, animated: false)
일부 주석 :
Segue와 함께이 작업을 수행 할 수 있습니다 . prepareForSegue
또는 에서 구현하십시오 shouldPerformSegueWithIdentifier
. 하나 기본 애니메이션도 그대로 유지됩니다. 이 문제를 해결하려면 스토리 보드로 이동하여 Segue를 클릭하고 ‘Animates’상자를 선택 취소하십시오. 그러나 이것은 IOS 9.0 이상의 앱을 제한합니다 (Xcode 7에서 가장 좋았습니다).
segue에서 수행 할 때 마지막 두 줄은 다음과 같이 바꿔야합니다.
self.navigationController?.popViewControllerAnimated(false)
내가 잘못 설정했지만 무시합니다.
답변
에 그 기억 스위프트 , 확장은 확실히 당신의 친구!
public extension UINavigationController {
/**
Pop current view controller to previous view controller.
- parameter type: transition animation type.
- parameter duration: transition animation duration.
*/
func pop(transitionType type: String = kCATransitionFade, duration: CFTimeInterval = 0.3) {
self.addTransition(transitionType: type, duration: duration)
self.popViewControllerAnimated(false)
}
/**
Push a new view controller on the view controllers's stack.
- parameter vc: view controller to push.
- parameter type: transition animation type.
- parameter duration: transition animation duration.
*/
func push(viewController vc: UIViewController, transitionType type: String = kCATransitionFade, duration: CFTimeInterval = 0.3) {
self.addTransition(transitionType: type, duration: duration)
self.pushViewController(vc, animated: false)
}
private func addTransition(transitionType type: String = kCATransitionFade, duration: CFTimeInterval = 0.3) {
let transition = CATransition()
transition.duration = duration
transition.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
transition.type = type
self.view.layer.addAnimation(transition, forKey: nil)
}
}
답변
Apple이 더 이상 앱을 승인하지 않기 때문에 개인 통화를 사용하는 것은 좋지 않습니다. 아마도 당신은 이것을 시도 할 수 있습니다 :
//Init Animation
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration: 0.50];
[UIView setAnimationTransition:UIViewAnimationTransitionCurlUp forView:self.navigationController.view cache:YES];
//Create ViewController
MyViewController *myVC = [[MyViewController alloc] initWith...];
[self.navigationController pushViewController:myVC animated:NO];
[myVC release];
//Start Animation
[UIView commitAnimations];