Things take time

[SWIFT] 4일차 : 스위프트 기본 앱 본문

iOS (교육)

[SWIFT] 4일차 : 스위프트 기본 앱

겸손할 겸 2017. 4. 8. 15:38

1. 페이지 뷰 : 코드로 직접 지정하기


import UIKit

class PageViewController: UIPageViewController, UIPageViewControllerDataSource {
    
    // lazy : 실제 그 변수가 사용되는 시점에 메모리 할당, 즉 앱 처음실행시엔 loadVC가 할당되지 않음 => setViewControllers에서 할당
    lazy var vcArray: Array = [self.loadVC("FirstVC"), self.loadVC("SecondVC"), self.loadVC("ThirdVC")]
    
    
    func loadVC(_ storyboardId: String) -> UIViewController{
        return (self.storyboard?.instantiateViewController(withIdentifier: storyboardId))!
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        self.dataSource = self
        // 이 시점에서 vcArray에 First, Second, Third가 할당이 됨
        self.setViewControllers([vcArray.first!], direction: .forward, animated: true, completion: nil)
        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    

    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

    // 이전 페이지 리턴
    @available(iOS 5.0, *)
    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController?{
        
        guard let curIndex = vcArray.index(of: viewController) else {
            return nil
        }
        
//        if let curIndex = vcArray.index(of: viewController){
//            
//        } else {
//            return nil
//        }
        
        let prePageIndex = curIndex - 1
        if prePageIndex < 0 {
            return vcArray.last
        } else {
            return vcArray[prePageIndex]
        }
    }
    
    // 이후 페이지
    @available(iOS 5.0, *)
    public func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController?{
        guard let curIndex = vcArray.index(of: viewController) else {
            return nil
        }
        
        let prePageIndex = curIndex + 1
        if prePageIndex >= vcArray.count {
            return vcArray.first
        } else {
            return vcArray[prePageIndex]
        }
    }
    
    
    // 페이지 카운트
    @available(iOS 6.0, *)
    public func presentationCount(for pageViewController: UIPageViewController) -> Int {
        
        return vcArray.count
    }
    
    // 시작페이지 인덱스
    @available(iOS 6.0, *)
    public func presentationIndex(for pageViewController: UIPageViewController) -> Int {
        
        return 0
    }
    
    // 페이지뷰 컨트롤러의 transition style을 스크롤로 지정했을 때, 하단에 생기는 검은색 바를 없애고 원래 화면을 꽉채우기 위함
    override func viewDidLayoutSubviews() {
        super.viewDidLayoutSubviews()
        
        for subview in self.view.subviews{
            if subview is UIScrollView{
                subview.frame = UIScreen.main.bounds
            }
        }
    }
}

* 버튼 간격 일정하게 조절하기

=> StackView를 생성하고, 해당 버튼들을 스택뷰 안에 넣고, 스택뷰의 attribute에서 Spacing을 조절하면 됨


2. 이미지 뷰 애니메이션 => 커스텀 인디케이터에 gif파일 대신 일반 png, jpg로 이용할 수 있음

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var imageView: UIImageView!
    var imageArray: [UIImage]? = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        for i in 1...10{
            imageArray?.append(UIImage(named: String(format: "%d.jpg",i))!)
        }
        imageView.animationImages = imageArray
        imageView.animationDuration = 1
        imageView.animationRepeatCount = -1
        imageView.startAnimating()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}


* 이미지 뷰에 로컬 파일을 추가할때, @2x, @3x를 파일 뒤에 붙여서 해상도 별 이미지를 저장해야 함


* 페이지 이동 시 이전 화면으로 돌아가는 방법

1) 일반 버튼으로 action show로 이동하게 된 경우

 self.presentingViewController?.dismiss(animated: true, completion: nil)

2) 네비게이션 컨트롤러를 바탕으로 bar button으로 이동한 경우

 // If this view controller has been pushed onto a navigation controller, return it.
        // 푸쉬(네비게이션을 통해 페이지 이동시 스택처럼 쌓임)
        self.navigationController?.popViewController(animated: true)

* 페이지 이동 방법(스토리보드 이용x), 네비게이션 컨트롤러 이용

이동할 VC(View Controller)의 스토리보드 아이디를 설정함, 만약 스토리보드가 2개이상이라면 아래와 같이 해당 스토리보드(큰 범위)를 가져오고, 그 스토리보드 안에서 검색

        let subStoryboard = UIStoryboard(name: "Sub", bundle: nil)
        let page4VC = subStoryboard.instantiateViewController(withIdentifier: "page4VC")
        self.navigationController?.pushViewController(page4VC, animated: true)

* 페이지 이동 방법2, 네비게이션 컨트롤러 이용

세그의 아이디를 알고 있다면 해당 세그를 실행시켜 페이지를 이동시킬 수 있음, 예를 들어 하나의 버튼을 눌러서 여러 VC중 하나로 가게하려면 아래처럼

        self.performSegue(withIdentifier: "4seg", sender: nil)

* 루트 VC로 이동하는 방법(현재 푸쉬된 뷰들을 무시하고)

        self.navigationController?.popToRootViewController(animated: true)

* 네비게이션 컨트롤러 없이 일반 modal VC로 이동하는 방법 : 네비게이션처럼 스택으로 쌓이지 않고 모달(팝업같은) 방식으로 됨

guard let modalVC = storyboard?.instantiateViewController(withIdentifier: "abc") else {
            return
        }
        present(modalVC, animated: true, completion: nil)