본문 바로가기
ios 뽀개기/ios 강좌

Ios AutoLayout 7 - AutoLayout Landscape 이슈

by 인생여희 2018. 5. 8.
반응형

Ios AutoLayout 7 - AutoLayout Landscape 이슈

● 들어가기 전

이번 포스팅에서는 Landscape을 했을때 발생하는 AutoLayout 이슈에 대해서 살펴보자. 글로 쓰는 것보다 사진을 바로 보자.

대충 이런 현상이다. 세로였을때 바로 나오다가  Landscape했을 때 위와 같이 두 페이지가 반반 씩 동시에 나오는 이슈가 발생한다. viewWillTransition 함수를 override 해서 해결해보자.

● 실습순서

1.viewWillTransition 함수 override
2.소스코드 리팩토링

● viewWillTransition 함수

아래의 viewWillTransitoin 함수는 view가 바뀔때 작동되는 함수다. 아래의 코드를 SwipingController 제일 윗 부분에 작성한다.  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        
        coordinator.animate(alongsideTransition: { (_) in
            //원래의 collectionViewLayout 기능을 정지 시킨다.
            self.collectionViewLayout.invalidateLayout()
            //페이지 컨트롤의 현재페이지가 0 이면
            if self.pageControl.currentPage == 0 {
                //오프셋을 .zero 로 설정
                self.collectionView?.contentOffset = .zero
            } else {
                //아니라면 넘겨지는 화면에 맞추기
                let indexPath = IndexPath(item: self.pageControl.currentPage, section: 0)
                self.collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
            }
            
        }) { (_) in
            
        }
    }
cs

● 소스코드 리팩토링

이제 모든 소스코드 작성이 끝났다. 마지막으로 SwipingController 안에 있는 소스코드를 정리해주도록 하겠다. SwipingController 안에는 UICollectionView를 구현하는 함수도 있고 위에 함수처럼 SwipingController 클래스를 확장시킨 함수도 있다. 먼저 SwipingController+UICollectionView.swift 파일을 만들어서 UICollectionView를 구현하는 함수만 따로 분리 시키자.

SwipingController+UICollectionView.swift
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
 
import UIKit
 
extension SwipingController{
    
    //컬렉션 뷰의 셀 사이사이마다 간격설정 원래는 디폴드 값으로 10이 지정되어 있음
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int-> CGFloat {
        return 0
    }
    //컬렉션 뷰의 cell 개수 지정.
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int-> Int {
        return pages.count
    }
    //컬렉션 뷰의 cell을 구성하는 함수
    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        //위에서 등록해준 커스텀 셀을 가져와서 리턴해줌
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId"for: indexPath) as! PageCell
        let page = pages[indexPath.item]
        //view에 page 변수에 할당
        cell.page = page
        return cell
    }
    //커스텀 셀의 크기를 view에 꽉차게 해주었다.
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: view.frame.width, height: view.frame.height)
    }
    
}
 
cs

마지막으로 SwipingController+extension.swift 파일을 만들어서 제일위  Landscape 이슈와 관련된 함수를 분리 시켜 주자. 그리고 SwipingController에서 pageControl의 접근 제어자 private을 삭제해주자. 그래야 SwipingController+extension.swift 파일 viewWillTransition 함수 내에서도 참조할 수 있다.

SwipingController+extension.swift

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
import UIKit
 
extension SwipingController {
    
    override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        
        coordinator.animate(alongsideTransition: { (_) in
            //원래의 collectionViewLayout 기능을 정지 시킨다.
            self.collectionViewLayout.invalidateLayout()
            //페이지 컨트롤의 현재페이지가 0 이면
            if self.pageControl.currentPage == 0 {
                //오프셋을 .zero 로 설정
                self.collectionView?.contentOffset = .zero
            } else {
                //아니라면 넘겨지는 화면에 맞추기
                let indexPath = IndexPath(item: self.pageControl.currentPage, section: 0)
                self.collectionView?.scrollToItem(at: indexPath, at: .centeredHorizontally, animated: true)
            }
            
        }) { (_) in
            
        }
    }
    
}
 
 
cs

● 파일

최종 파일은 아래와 같다. 따로 폴더를 만들어서 MVC패턴으로 더 깔끔하게 정리해줘도 될것 같다.

● 실행

마지막으로 실행을 해보면 이제  AutoLayout Landscape 이슈가 해결된 것을 볼 수 있다.

● 마무리

Ios AutoLayout 포스팅을 하면서 UIPageControl, button 이벤트, UICollectionView, AutoLayout 함수, 계층 구조를 이용해서 부모View에 자식View 넣기, UIStackView가 배열 타입이라는 것, MVC 패턴, extension 개념 등등 ios의 다양한 지식과 기술을 익힌것 같다. 이것들을 더 응용해서 새로운 ios 앱을 만들어 보면 실력향상에 더욱 좋을 것 같다. 감사합니다.  





반응형

댓글