top of page
Matt

iOS용 스위프트에서 비디오 배경 뷰 컨트롤러 만들기: 단계별 가이드

이 튜토리얼에서는 반복해서 비디오 배경이 재생되는 iOS 스위프트에서 ViewController를 만드는 방법을 보여줄 것입니다.


목차


아래 예시는 도쿄의 밤 장면을 반복 재생하는 배경 비디오가 있는 간단한 메뉴를 보여줍니다:




장단점

먼저 이것을 왜 하고 싶은지 탐구해 보겠습니다. 하지만 코드로 바로 가고 싶다면, [여기]를 클릭하세요.


장점

  • 미적 매력: 비디오 배경은 앱을 더 역동적이고 매력적으로 만들어 사용자의 시각적 경험을 향상시킬 수 있습니다.

  • 브랜드 표현: 앱 내에서 브랜드 정체성을 전달하거나 특정 분위기를 조성하는 데 효과적인 방법이 될 수 있습니다.

  • 사용자 참여: 잘 선택된 비디오는 사용자의 관심과 참여를 증가시켜, 잠재적으로 더 긴 세션 시간으로 이어질 수 있습니다.

  • 스토리텔링: 비디오는 정지 이미지나 텍스트보다 더 몰입감 있게 이야기를 전달하거나 정보를 전달하는 데 사용될 수 있습니다.

  • 맥락 정보: 경우에 따라 비디오 배경은 앱의 내용이나 기능과 관련된 유용한 맥락이나 정보를 제공할 수 있습니다.


단점

  • 성능 영향: 비디오 재생은 리소스를 많이 사용할 수 있으며, 배터리 소모 증가 및 앱 성능 감소로 이어질 수 있습니다.

  • 앱 크기 증가: 비디오 파일을 포함하면 앱의 크기가 크게 증가할 수 있으며, 저장 공간이 제한된 사용자에게 문제가 될 수 있습니다.

  • 산만함: 주의 깊게 사용하지 않으면 비디오 배경은 사용자에게 산만할 수 있으며, 중요한 내용이나 기능에 집중하기 어렵게 만들 수 있습니다.

  • 데이터 사용: 비디오가 인터넷에서 스트리밍되거나 다운로드될 경우 상당한 양의 데이터를 사용할 수 있으며, 데이터 요금제가 제한된 사용자에게 이상적이지 않을 수 있습니다.

  • 접근성 문제: 특히 깜박거리거나 빠르게 움직이는 요소가 있는 비디오는 특정 장애나 민감성이 있는 사용자에게 문제가 될 수 있습니다.

  • 로딩 시간: 비디오를 통합하면 특히 모바일 사용에 최적화되지 않은 비디오의 경우 뷰 컨트롤러의 로딩 시간이 증가할 수 있습니다.


모범 사례

  • 성능 및 로딩 문제를 최소화하기 위해 비디오가 모바일 기기에 적절하게 최적화되어 있는지 확인합니다.

  • 간단한 인터페이스를 선호하거나 배터리/데이터를 절약해야 하는 사용자를 위해 비디오 배경을 비활성화하는 옵션을 제공하는 것을 고려합니다.

  • 비디오 콘텐츠를 사용할 수 없는 사용자를 위한 대체 콘텐츠를 제공하는 등 접근성 지침을 준수하는 것이 중요합니다.

  • 비디오 콘텐츠를 앱의 목적과 관련 있게 유지하고 사용자 경험을 향상시키는 것이 중요합니다.


요약하자면, 비디오 배경은 시각적으로 눈에 띄고 매력적일 수 있지만, 성능, 접근성 및 사용자 경험과 관련된 잠재적 단점과 이점을 균형 있게 고려하는 것이 중요합니다.


단계별 비디오뷰컨트롤러

1. 필요한 프레임워크 가져오기

import UIKit
import AVKit
import AVFoundation

필요한 프레임워크를 가져오기 시작합니다:

  • UIKit: 이것은 iOS 인터페이스를 구축하기 위한 기본 프레임워크입니다.

  • AVKit 및 AVFoundation: 이들은 비디오 재생에 필수적인 오디오-비주얼 미디어를 처리하는 데 사용됩니다.


2. 비디오뷰컨트롤러 클래스 정의

class VideoViewController: UIViewController {
    var videoName: String

여기서 UIViewController에서 상속받는 새로운 클래스 VideoViewController를 정의합니다. 또한 비디오 파일의 이름을 저장할 변수 videoName을 선언합니다.


3. 비디오 재생을 위한 속성 정의

fileprivate var queuePlayer: AVQueuePlayer?
fileprivate var playerLayer: AVPlayerLayer?
fileprivate var playbackLooper: AVPlayerLooper?
  • queuePlayer: 재생 큐를 관리하기 위한 AVQueuePlayer 객체.

  • playerLayer: 뷰의 레이어에 비디오 콘텐츠를 표시하는 AVPlayerLayer.

  • playbackLooper: 비디오의 원활한 루핑을 용이하게 하는 AVPlayerLooper.


4. 컨트롤러 초기화

init(videoName: String) {
    self.videoName = videoName
    super.init(nibName: nil, bundle: nil)
}

이 초기화 함수는 videoName 속성을 설정하고 상위 클래스의 초기화 함수를 호출합니다. 올바른 파일을 재생하기 위해 비디오 이름이 필요하기 때문에 이 사용자 지정 init이 필요합니다.


5. viewDidLoad 오버라이드

override func viewDidLoad() {
    super.viewDidLoad()
    
    playBackgroundVideo()
}

viewDidLoad 메소드에서 playBackgroundVideo()를 호출합니다. 이 메소드는 뷰 컨트롤러의 뷰가 메모리에 로드될 때 실행됩니다.


6. 비디오 파일 찾기

guard let path = Bundle.main.path(forResource: videoName, ofType: "mp4") else {
    return
}

여기서 앱 번들에서 비디오 파일의 경로를 찾으려고 합니다. 만약 그것이 존재하지 않으면, 함수는 일찍 반환합니다.

7. 플레이어 설정

let playerItem = AVPlayerItem(url: URL(fileURLWithPath: path))
self.queuePlayer = AVQueuePlayer(playerItem: playerItem)
self.playerLayer = AVPlayerLayer(player: self.queuePlayer)

비디오 URL을 가진 AVPlayerItem을 생성한 다음, 그것으로 queuePlayer와 playerLayer를 초기화합니다.


8. 루핑 및 레이어 구성

guard let playerLayer = self.playerLayer else { return }
guard let queuePlayer = self.queuePlayer else { return }
self.playbackLooper = AVPlayerLooper.init(player: queuePlayer, templateItem: playerItem)
playerLayer.videoGravity = .resizeAspectFill
playerLayer.frame = self.view.bounds
self.view.layer.addSublayer(playerLayer)
  • 비디오를 루핑하기 위해 playbackLooper를 구성합니다.

  • videoGravity를 resizeAspectFill로 설정하여 비디오가 종횡비를 유지하지 않고 전체 뷰 영역을 커버하도록 합니다.

  • playerLayer의 프레임을 뷰의 경계에 맞게 설정합니다.

  • playerLayer를 뷰의 레이어의 하위 레이어로 추가합니다.


9. 비디오 재생 시작

queuePlayer.play()

마지막으로, 비디오를 재생합니다.

이 코드는 무한히 반복되는 전체 화면 비디오 배경이 있는 뷰 컨트롤러를 생성합니다. 비디오 파일은 앱 번들에 포함되어야 하며 VideoViewController 인스턴스를 생성할 때 그 이름으로 지정되어야 합니다.


VideoViewController:

import UIKit
import AVKit
import AVFoundation

class VideoViewController: UIViewController {
    var videoName: String
    
    fileprivate var queuePlayer: AVQueuePlayer?
    fileprivate var playerLayer: AVPlayerLayer?
    fileprivate var playbackLooper: AVPlayerLooper?
    
    init(videoName: String) {
        self.videoName = videoName
        super.init(nibName: nil, bundle: nil)
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        playBackgroundVideo()
    }

    func playBackgroundVideo() {
        guard let path = Bundle.main.path(forResource: videoName, ofType: "mp4") else {
            return
        }
        
        let playerItem = AVPlayerItem(url: URL(fileURLWithPath: path))
                
        self.queuePlayer = AVQueuePlayer(playerItem: playerItem)
        self.playerLayer = AVPlayerLayer(player: self.queuePlayer)
        guard let playerLayer = self.playerLayer else { return }
        guard let queuePlayer = self.queuePlayer else { return }
        self.playbackLooper = AVPlayerLooper.init(player: queuePlayer, templateItem: playerItem)
        
        playerLayer.videoGravity = .resizeAspectFill
        playerLayer.frame = self.view.bounds
        self.view.layer.addSublayer(playerLayer)
        
        queuePlayer.play()
    }
}

예시 사용, 메뉴뷰컨트롤러:

import UIKit

class MenuViewController: VideoViewController {
    init() {
        super.init(videoName: "MenuVideo")
    }

    required init?(coder: NSCoder) {
        super.init(videoName: "MenuVideo")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        
        setUpButtons()
    }

    fileprivate func setUpButtons() {
        let playGameButton = UIButton()
        playGameButton.translatesAutoresizingMaskIntoConstraints = false
        playGameButton.setTitle("Play Game", for: .normal)
        playGameButton.setTitleColor(.black, for: .normal)
        playGameButton.backgroundColor = .white
        playGameButton.addTarget(self, action: #selector(playGameButtonTapped), for: .touchUpInside)
        self.view.addSubview(playGameButton)
        
        let optionsButton = UIButton()
        optionsButton.translatesAutoresizingMaskIntoConstraints = false
        optionsButton.setTitle("Options", for: .normal)
        optionsButton.setTitleColor(.black, for: .normal)
        optionsButton.backgroundColor = .white
        optionsButton.addTarget(self, action: #selector(optionsButtonTapped), for: .touchUpInside)
        self.view.addSubview(optionsButton)
        
        NSLayoutConstraint.activate([
            playGameButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            playGameButton.centerYAnchor.constraint(equalTo: self.view.centerYAnchor, constant: -30),
            playGameButton.widthAnchor.constraint(equalToConstant: 200),
            playGameButton.heightAnchor.constraint(equalToConstant: 50),

            optionsButton.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
            optionsButton.topAnchor.constraint(equalTo: playGameButton.bottomAnchor, constant: 20),
            optionsButton.widthAnchor.constraint(equalToConstant: 200),
            optionsButton.heightAnchor.constraint(equalToConstant: 50)
        ])
    }

    @objc func playGameButtonTapped() {
        print("Play Game button pressed")
    }

    @objc func optionsButtonTapped() {
        print("Options button pressed")
    }
}

지원 방법

이 콘텐츠는 항상 무료로 제공될 것이며, 가치 있다고 생각되면 다른 사람들과 공유하는 것을 고려해 주세요. 또한, 우리의 게임을 다운로드하고 솔직한 리뷰를 남기는 것은 우리를 크게 지원합니다. 질문이나 피드백이 있으면 언제든지 연락 주시고, 최선을 다해 응답하겠습니다.


오늘 애플 앱 스토어에서 Falling Sky를 다운로드하세요: https://apps.apple.com/app/id6446787964


X에서 우리를 팔로우하세요: https://x.com/_kingdomarcade

조회수 6회
bottom of page