Popup

이세진·2022년 6월 24일
0

iOS

목록 보기
14/46

생성일: 2021년 11월 19일 오후 9:31

1 단계

새로운 VC를 만들고 팝업창 뷰를 만들었다. 이때 회색 뷰(내부의 이미지와 Labe, button을 감싸기 위해 만든) 에 가운데 정렬을 제외한 어떠한 Constraint를 주지 않고도 에러를 없앨 수 있다. 오토레이아웃의 핵심인 위치 설정과 크기 설정 중에 위치 설정만 한 것인데 말이다.

방법은 바로 내부의 ui들에 constraint를 주는 것이다.

내부에 있는 이미지와 버튼들에게 회색 view와의 거리 constraint를 주어서 회색 view에 직접적으로 constraint를 주지 않아도 내부 ui들의 크기와 위치가 설정되면 그것을 자동으로 감싸는 만큼의 크기가 되는 것이다.

보라색 이미지의 상단에 0, 아래 버튼의 하단에 20의 constraint를 주면 위와 같이 에러가 없어지고 회색 뷰의 크기가 맞추어진다.

  • 이렇게 했을 때의 장점
    • 가운데 Label의 크기가 가변적으로 커져도 회색 뷰의 크기가 이것을 감쌀 만큼 알아서 커진다. (딱 정해진 크기를 Contraint로 주지 않았기 때문)

2 단계

위와 같이 풍선 이미지와 체크 이미지를 팝업창과 바깥 부분에 걸치게 만들고 싶다면 어떻게 해야 할까?

  1. 이미지 뷰를 만들고 팝업 뷰안에 넣는다.
  2. 필요한 위치에 맞게 팝업뷰와 이미지 뷰의 alignment를 조절한다. (여기서 체크 이미지 기준으로 Top과 Trailing edge에 정렬시켰다.)
  3. 기본적인 방법은 top edge에 정렬시킨 contraint에서 constant값을 바꾸는 것이다. (단점은 비율로 설정한 것이 아니라서 기기마다 위치가 조금씩 바뀔 수 있다.)
  4. 다른 방법은 3번의 constraint에서 multiplier값을 변경하는 것이다 ⇒ 위와 같은 사례에서는 불가능 Why? multiplier는 말 그대로 비율(배율)을 변경하는 것인데 기본 constraint값이 0 이기 때문에 Multiplier를 다른 값으로 변경해도 ui의 위치에는 변화가 없게 된다.
  5. 마지막 방법
    1. 2번에서 Top edge에 정렬시킨 constraint를 더블 클릭하여 확인하면 First Item 혹은 Second Item에 해당 이미지가 있을것이다.
    2. 이 이미지가 이미지이름.Top으로 되어 있을 텐데 이것을 CenterY로 변경한다
    3. 이것은 이미지와 팝업 뷰의 Top이 서로 같게 정렬되어 있는 상태에서 이미지의 Y축 중간값과 팝업 뷰의 Top이 같도록 설정하는 것이다.
    4. 이렇게 하면 위 사진의 풍선이미지와 체크 이미지 처럼 팝업뷰 상단의 중간에 걸치게 설정할 수 있다.
    5. 체크 이미지는 Trailing edge 설정을 CenterX로 바꾸는 작업이 추가된 것이다.

3단계

Main 스토리보드에서 있는 버튼을 클릭하면 지금까지 만든 팝업창이 뜨도록 구현해보자.

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func showPopup(_ sender: UIButton) {
        
        // 1. PopupViewController 스토리보드 가져오기
        let storyBoard = UIStoryboard.init(name: "PopupViewController", bundle: nil)
        
        // 2. VC 가져오기
        let popupVC = storyBoard.instantiateViewController(withIdentifier: "popupVC")
        // 1,2번은 일종의 공식과 같은 방법
        
        // 투명도(opacity)가 배경화면에 있다면 해당 VC에 투명도를 적용시킴 (투명도가 필요하다면 꼭 해줘야 함)
        popupVC.modalPresentationStyle = .overCurrentContext
        
        // 해당 VC 띄우기
        self.present(popupVC, animated: false) {
        }
        
    }
    
}

해당 버튼과 VC를 IBAction으로 연결한다.

  1. Popup 스토리보드 객체를 생성한다.
  2. 해당 스토리보드의 VC 객체를 생성한다. (이때 identifier는 스토리보드의 inspector에 있는 Storyboard ID 이다.)

1, 2번은 일종의 공식과 같은 방법으로 숙지해놓아야 한다.

  • 팝업창이 투명한 검정색 배경을 가지게 하고 싶을 때
    • Popup storyboard의 배경 View에 background를 검은색으로 선택한다.
    • 두가지 선택지
      1. Alpha값을 기본값인 1에서 0.5 정도로 바꾼다.
        1. 문제점 : 해당 View에 속한 다른 요소들도 전부 투명도를 가진다.
      2. background color를 custom으로 바꾸고 custom 창의 opacity를 드래그하여 변경한다.
        1. 이렇게 하면 배경 view의 색상만 투명해진다.
    • 원하는 것은 배경화면만 투명해지는 것이므로 opacity를 변경했다.
    • 코드에서 해당 VC를 present 하기전에
      popupVC.modalPresentationStyle = .overCurrentContext
      이 코드를 추가해 주어야 opacity가 정상적으로 적용된채로 불러와진다.
import UIKit

class PopupViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

    }

    @IBAction func closePopup(_ sender: UIButton) {
        self.dismiss(animated: false, completion: nil)
    }
    
}

PopupVC에 팝업창에 있는 버튼을 연결시키고 클릭시 팝업창이 사라지도록 dismiss 를 넣어주었다.

4단계

지금까지의 팝업창의 초록색 체크 이미지는 버튼이 아니라 image view이기 때문에 터치를해도 팝업창을 사라지게 하는 기능을 추가 할 수 없다. ⇒ 버튼으로 해당 기능을 하도록 다시 만들어 보자

이때 중요한 점

  • 버튼을 팝업 뷰 (풍선이미지가 달린 뷰) 안에 넣어서 생성하고 2단계의 방식으로 정렬시키면 문제가 발생한다.

    • 문제점
      • 이렇게 하면 동그란 버튼의 일부분이 사각형인 팝업뷰의 바깥으로 일부분이 튀어나온다. (의도한 부분)
      • 그런데 이렇게 튀어나온 부분은 터치나 클릭이 되지 않는다. (안쪽 부분은 가능)
    • 해결책
      • 버튼을 생성하거나 정렬시킬때 팝업뷰 바깥에 위치시키고 2단계의 방법으로 정렬시켜야한다.
  • 간혹 버튼에 이미지를 넣고 크기 constraint를 주었는데도 크기가 줄어들지 않는 문제

    • 해결책
      1. 해당 버튼의 title을 없앤다.

      2. button의 type을 custom으로 바꾼다.

      3. button의 Style과 StateConfig를 Default로 바꾼다.

        1~3번을 골고루 적용시켜보면 원하는 크기로 설정할 수 있게 된다.

최종구현

profile
나중은 결코 오지 않는다.

0개의 댓글