2015-01-01 2 views
4

나는 데 어떤 문제를 보여주는 비디오에 대한 링크를 포함 시켰습니다 :키보드가 Xcode 6에 나타나면 사라지는보기를 수정하는 방법?

https://dl.dropboxusercontent.com/u/39330138/Bug_Demo1.mov

두보기 컨트롤러가 있습니다를, 최초의 비 흐리게하고 덜 중요하다. 더하기 버튼을 클릭하면 앱이 애니메이션없이 새 컨트롤러에 연결되고 prepareForSegue()에 나는 현재보기에서 UIImage을 캡처하여 다음보기로 전달하기 위해 과 UIGraphicsGetImageFromCurrentImageContext을 사용합니다.

새보기가 나타날 때 나는 흐림보기를 만들고이를 '배경'인 이미지보기에 하위보기로 추가하기 위해 UIVisualEffectView을 사용합니다. 그런 다음 불투명도가 애니메이션화되고 동시에 2 개의 뷰와 2 개의 버튼이 UIView 애니메이션 및 springWithDamping의 애니메이션으로 화면에 표시됩니다. 이로 인해 뷰가 흐릿 해 보이고 맨 위에 애니메이션이 적용됩니다.

상위 뷰는 UITextField 통화 becomeFirstResponder()를 도청하고 모든 중첩을 할 때, 이미지보기가 사라 배경에 새겨 져 비주얼 효과보기를 포함 조회수 (새 세션이 & 버튼 태그)를하는 그 안에 포함 된 있습니다.

내가 자세히 설명하는 이유는 정확히 무엇이 문제인지 정확히 알 수 없기 때문입니다. 그러나 Xcode 6의 AutoLayout/Size Classes와 관련이 있다는 의혹이 있습니다.

왜 이런 일이 벌어지고 어떻게 고치려하는지 알 수 있습니까? 추가 정보가 필요하면 알려주세요.

감사합니다.

편집 : 나는이 텍스트 필드를 클릭 한 후 뷰를 기록 할 때

, 모든 프레임은 같은 것 같다.

편집 2 : 여기

는 데모 프로젝트에 대한 링크의 뜻 비디오의 모든 기능 : https://dl.dropboxusercontent.com/u/39330138/DEMO%20APP.zip

+0

누구나이 질문이 너무 어렵거나 (많은) 정보가 더 필요하다고 생각하면 프로젝트 파일을 첨부하여 보내 주시면 기쁩니다. – nanothread59

+0

데모 프로젝트를 첨부 할 수 있습니까? –

+0

@LeoNatan 물론, 잠시만 기다려주세요 ... – nanothread59

답변

1

가 여기 일이 몇 가지가 있지만, 주범은 viewDidLayoutSubviews()의 사용입니다 . 이것은 시스템이 레이아웃을 재평가 할 때마다 호출됩니다. 나는 당신이 1alpha 애니메이션을보기 때문에보기가 나타납니다 전에 한 번만 호출 할이를하려는 것 같아

if !returningFromTagView { 
    blurView.alpha = 0 
} 

: 나는 당신이 그 방법에 UIVisualEffectViewalpha0로 설정하고 참조 viewDidAppear(animated: Bool). 그러나 시스템이 어떤 이유로 든 레이아웃을 재평가 할 때마다 viewDidLayoutSubviews()이 호출되고 alpha (blurView)은 이 false 인 경우 0으로 되돌아갑니다. 그래서 키보드를 소환 할 때 (레이아웃 재평가 트리거)이보기가 사라집니다. Xcode는 콘솔에 alpha0을 만들 것을 경고합니다. 불투명도가 1이 될 때까지는 시각적 인 효과가 없습니다. 위의 코드를 viewDidLoad() 메소드에 넣으면 blurView이 다시 표시됩니다. 보기가로드 될 때 alpha0으로 한 번만 설정하면됩니다.

다른보기의 문제는 약간보기가 어렵지만 다시 한 번 viewDidLayoutSubviews()을 사용합니다. 나는 당신이 프레임을 설정하고,보기를 앞으로 가져오고, 숨겨져 있지 않은지 확인하고, 이것을 기록하기 위해 당신의 keyboardNotfication() 메소드에서 철저히 조사한 후에도 화면이 나타나지 않는 이유에 대해 의아하게 생각합니다. 모든. 그러나 keyboardNotification() 방법이 완료된 후, 다시 한 번 레이아웃 시스템은 트리거, 그리고 당신이 여기 저기 뷰 '프레임을 이끌어 있다는 것을 참조 :

if returningFromTagView {    
    setX(-titleView.frame.size.width, v: titleView) 
    setX(-tagView.frame.size.width, v: tagView) 
    setX(-(cancelButton.frame.size.width + 20 + nextButton.frame.size.width), v: cancelButton) 
    setX(-nextButton.frame.size.width, v: nextButton) 
} else { 
    setX(-titleView.frame.size.width, v: titleView) 
    setX(view.frame.size.width, v: tagView) 
    setX(-cancelButton.frame.size.width, v: cancelButton) 
    setX(view.frame.size.width, v: nextButton) 
} 

당신은 때마다 레이아웃 변경 오프 스크린 뷰를 이동하고 만들어집니다! Xcode 6의 탁월한 새로운 캡처 뷰 계층 구조 기능을 사용하여 키보드를 소환하고 뷰 계층을 살펴본 후 프로그램을 일시 중지하십시오. 디버그> 디버깅보기> 캡처 뷰 계층 구조에 있습니다. 그 견해는 옆으로 숨어 있습니다.

전이 애니메이션을 지원하기 위해 뷰가 표시 될 때이 작업을 한 번만 수행하면되지만 이미지가 표시되는지 또는 키보드와 같은 작은 변화가 나타나는지 여부는 호출됩니다. 이 애니메이션을 다른 방법으로 구현하는 것이 좋습니다 (예 : 스토리 보드에서 많은 누락 된 구속 조건이 있지만보기 변환을 사용하거나 자동 레이아웃 제약 조건을 사용하는 등). viewDidLayoutSubviews()은 실제로 레이아웃 시스템이 작업을 완료 한 후에 레이아웃에서 물건을 퍼지 할 장소입니다. 당신은 그것을 사용해야 할 정당한 이유가 있어야합니다. autolayout 제약 조건을 재정의하고 제약 조건을 무시하지 않고 해당 뷰를 애니메이션화 할 수있는 좋은 기능이 있습니다 (메서드가 updateConstraints()layoutSubviews() 메서드 이후에 발생하기 때문에) 위의 코드를 viewWillAppear(animated: Bool)과 같은 메서드에 넣을 수없는 이유가 여기에 있습니다 대신에 (레이아웃 도중 자동 레이아웃 제약이 애니메이션에 반영되기 때문에) viewDidLayoutSubviews()은 기본 애니메이션을 지원하기위한 방법이 아닙니다.

그럼에도 불구하고 다음은 앱을 다시 시작하고 진행 상황을 볼 수있는 간단한 내용입니다. NewSessionVC보기 컨트롤러에 대한 속성을 var comingFromSessionView: Bool으로 설정하십시오. SessionVC의 prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)에서 nextVC.comingFromSessionView = true

다음이에 위 viewDidLayoutSubviews()에서 코드 블록을 변경, 추가 :

if returningFromTagView { 
    setX(-titleView.frame.size.width, v: titleView) 
    setX(-tagView.frame.size.width, v: tagView) 
    setX(-(cancelButton.frame.size.width + 20 + nextButton.frame.size.width), v: cancelButton) 
    setX(-nextButton.frame.size.width, v: nextButton) 

} else if comingFromSessionView { 
    setX(-titleView.frame.size.width, v: titleView) 
    setX(view.frame.size.width, v: tagView) 
    setX(-cancelButton.frame.size.width, v: cancelButton) 
    setX(view.frame.size.width, v: nextButton) 
} 

우리는 viewDidAppear 동안 false 이러한 Bool의 전환 것이 그들과 함께 끝났다 후 :

override func viewDidAppear(animated: Bool) { 
    ... 
    if returningFromTagView { 
     ... 
     returningFromTagView = false 
    } else if comingFromSessionView { 
     ... 
     comingFromSessionView = false 
    } 
} 

이제 키보드를 불러 오면보기를 그대로 두었습니다.

위 코드는 좋지 않습니다. 나는이 애니메이션을하기 위해 오히려 viewDidLayoutSubviews()에서 멀리 떨어져있을 것입니다. 그러나 잘하면 당신은 지금 무슨 일이 일어나고 있는지 볼 수 있습니다. viewsDidLayoutSubviews() 님이 내 의견을 털어 놓았습니다.

+0

정말 고마워요, 이건 정말 환상적인 대답입니다. 나는 키보드가 나타 났을 때'viewDidLayoutSubviews()'가 호출되었다는 것을 알지 못했다. 완벽하게 내 문제를 해결! – nanothread59

+0

나는 상향 투표했고, 받아 들였고, 6 시간 만에 현상금을 수여 할 것이다 (나는 수여되기 적어도 1 일을 기다려야한다) – nanothread59