프론트엔드/Swift

[Swift] ImageView app 화면 만들기

dotudy 2024. 10. 6. 02:01

스위프트하면 테일러 스위프트부터 생각나는뒙ㅎ 어쩌다 이름이 스위프트 

 

 

View: 사용자가 보고 클릭하고 입력하는 모든 화면을 보여주는 캔버스이다. 당연히 한 화면에서 보여지는 것은 하나의 뷰로 하나 이상의 뷰를 사용할 때는 여러 개의 뷰를 겹쳐 놓은 후에 뷰를 선택하게 해야 한다. 

 

Image view: 이미지 뷰는 앱에서 사진을 보여줘야 할 때 사용하는 객체이다. 이미지가 나오는 모든 앱에서 해당 이미지 뷰를 사용하고 있다. 

기기별로 권장하는 이미지 사이즈가 있으니 iOS 개발자 문서를 참고하여 권장 이미지 해상도를 확인하면 되겠다. 

 

일단 사용할 이미지를 프로젝트 밑에 추가해야한다. 드래그 드롭해주면 파일 추가에 대한 설정 창이 나타나는데 [Destination: Copy items if needed] 항목에 체크를 하고 Finish해준다.

 

Library에서 ImageView를 찾아서 드래그 드롭해준다. 크기를 조정해서 다음과 같이 만들고 View의 Content Mode가 Aspect Fit인지 확인한다. Option을 누른 채 마우스를 사용해 크기를 조절하면 상하좌우의 여백의 숫자를 확인할 수 있다. 

 

Content Mode에 따라 보이는 이미지가 다르다.

1. Scale to Fill

이미지 뷰의 크기에 맞게 이미지의 비율이 변경된다.

2. Aspect Fit

이미지의 가로, 세로 비율이 유지되면서 이미지 뷰의 크기에 맞게 이미지 크기가 바뀐다.

3. Aspect Fill

이미지의 비율을 유지하면서 이미지 뷰를 채운다. 비율이 맞지 않으면 이미지가 밖으로 벗어나서 짤린다.

4. Center

이미지의 원본 크기를 유지한 채 중앙을 이미지 뷰에 보여준다.

5. Top

이미지의 원본 크기를 유지한 채 윗부분을 이미지 뷰에 보여준다.

6. Top Left

이미지의 원본 크기를 유지한 채 왼쪽 윗부분을 이미지 뷰에 보여준다.

 

이미지를 확대 축소할 수 있도록 Libaray에서 Button을 찾아 드래그 드롭한다. Attributes inspector에서 Style을 default로 변경하고 버튼의 글자를 '확대'로 바꾼다.

이미지를 변경할 수 있도록 Library에서 Switch를 찾아 드래그 드롭한다. 

 

일반적으로 버튼은 한 가지 일을 하도록 지시하고 스위치는 On/Off 상태를 바꾸는 역할을 한다.

다음과 같이 화면이 완성된다. 

 

 

화면을 완성했으니 이제 아웃렛 변수와 액션 함수를 추가해야한다.

보조 편집기(Assistant editor) 영역을 열어서 소스를 편집해야한다.

 

이미지 뷰를 마우스 오른쪽 버튼으로 선택하고 ViewController의 클래스 선언문 바로 밑에 놓는다. 아웃렛 변수는 일반적으로 클래스 선언문 바로 아래에 추가한다. 

connection이 [Outlet]으로 되어있고 Name: imgView라고 입력하고, Type: UIImageView인 것을 확인하고 연결 버튼을 누른다. 

 

마찬가지로 확대에도 아웃렛 변수를 추가해보자. connection이 [Outlet]으로 되어있고 Name: btnResize라고 입력하고, Type: UIButton인 것을 확인하고 연결 버튼을 누른다. 

 

확대 버튼은 눌리기도 해야되고 이미지를 실제로 확대하는 액션이 필요하니 액션함수도 추가해야한다. 이제 확대 버튼에 액션 함수를 추가해보자.

오른쪽 마우스로 소스 코드 가장 아랫부분에 드래그드롭하자. 

connection이 [Action]으로 되어있고 Name: btnResizeImage라고 입력하고, Type: UIButton로 설정하고 연결 버튼을 누른다. 어떤 타입의 객체에서 액션이 발생했을 때 이 액션 함수를 실행해야한다고 설정하는 것이다. Any type으로 설정하면 자동으로 선택되는데 동작에는 문제가 없지만 화면이 복잡해지면 문제가 발생할 수도 있기에 객체를 정확하게 지정해주는 것이 중요하다. 

 

@IBAction func btnResizeImage(_ sender: UIButton) {
    }

그러면 이렇게 코드가 추가된다. 

마지막으로 스위치에도 액션함수를 추가해주자. 

connection이 [Action]으로 되어있고 Name: switchImageOnOff라고 입력하고, Type: UISwitch으로 바꾸고 연결 버튼을 누른다. 

 

여기까지하면 ViewController.swift 코드는 다음과 같이 된다. 


import UIKit

class ViewController: UIViewController {
    @IBOutlet var imgView: UIImageView!
    
    @IBOutlet var btnResize: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func btnResizeImage(_ sender: UIButton) {
    }
    @IBAction func switchImageOnOff(_ sender: UISwitch) {
    }
    
}

이제 버튼을 클릭했을 때 또는 스위치를 On/Off했을 때 어떠한 동작을 수행하도록할지 코딩할 준비가 끝났다.

 

뷰 컨트롤러에 변수를 추가한다.

 

* 옵셔널 변수

스위프트에서는 변수 선언 뒤에 ?가 붙는 경우가 있다. 이는 옵셔널이라는 개념이다. 옵셔널은 어떤 값이 존재하지 않는다는 것을 나타낼 때 사용한다. 즉, 해당 변수가 nil(NULL)이거나 값의 존재 여부를 알 수 없다는 것을 뜻한다. 스위프트에서는 변수를 선언할 때 항상 nil이 아닌 값을 할당해야 하지만 옵셔널 타입을 사용해서 변수에 값이 없다고 알리면서 선언할 수 있다. 초깃값을 항상 주어야하는지 주지 않았기 때문에 ?를 붙여서 값이 없을 수 있다를 넣어주는 것이다. 옵셔널로 선언된 변수에 값이 할당되면 그 값은 '옵셔널에 wrapped되었다'고 한다. 이 값은 !를 사용하여 강제 언래핑(force unwrapping)하여 값에 접근할 수 있다. 암묵적인 언래핑(implicity unwrapping)이 되도록 선언할 수 있는데 이때는 강제 언래핑을 사용하지 않아도 값에 접근할 수 있다.

위는 강제 언래핑을 통해 값에 접근한 것이고 아래는 사용하지 않고 값에 접근한 것이다.

 

UIImage 타입의 변수에 이미지를 지정해주는 코드를 추가한다.


import UIKit

class ViewController: UIViewController {
    var isZomm = false
    var imgOn: UIImage?
    var imgOff: UIImage?
    @IBOutlet var imgView: UIImageView!
    
    @IBOutlet var btnResize: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        imgOn = UIImage(named: "lamp_on.png")
        imgOff = UIImage(named: "lamp_off.png")
        
        imgView.image = imgOn
    }

    @IBAction func btnResizeImage(_ sender: UIButton) {
    }
    @IBAction func switchImageOnOff(_ sender: UISwitch) {
    }
    
}

 

imgView.image에 imgOn을 대입했으니 앱을 실행하면 이제 lamp_on.png 이미지가 나타날 것이다. 

여기서 viewDidLoad()함수는 내가 만든 뷰를 불러왔을 때 호출되는 함수로 뷰가 불러진 후 실행하고자 하는 기능이 필요할 때 해당 함수 내에 코드를 입력한다.

 

이제 확대 버튼을 누르면 동작하게끔 코드를 추가해주겠다. 

그리고 옆에 있는 스위치 On/Off를 누르면 스위치 상태에 따라 이미지 뷰에 나타날 사진을 변경해주는 코드를 넣어준다.

 

이렇게 잘 동작하는 것을 확인할 수 있다. 

 


import UIKit

class ViewController: UIViewController {
    var isZoom = false
    var imgOn: UIImage?
    var imgOff: UIImage?
    @IBOutlet var imgView: UIImageView!
    
    @IBOutlet var btnResize: UIButton!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        
        imgOn = UIImage(named: "lamp_on.png")
        imgOff = UIImage(named: "lamp_off.png")
        
        imgView.image = imgOn
    }

    @IBAction func btnResizeImage(_ sender: UIButton) {
        let scale:CGFloat = 2.0
        var newWidth:CGFloat, newHeight: CGFloat
        
        if(isZoom){ // true
            newWidth = imgView.frame.width/scale
            newHeight = imgView.frame.height/scale
            btnResize.setTitle("확대", for: .normal)
        }
        else{ // false
            newWidth = imgView.frame.width*scale
            newHeight = imgView.frame.height*scale
            btnResize.setTitle("축소", for: .normal)
        }
        imgView.frame.size = CGSize(width: newWidth, height: newHeight)
        isZoom = !isZoom
    }
    
    @IBAction func switchImageOnOff(_ sender: UISwitch) {
        if sender.isOn {
            imgView.image = imgOn
        }else{
            imgView.image = imgOff
        }
    }
    
}