You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift 4中如何解决动画背景遮挡界面按钮的问题?

Fixing Your Video Background Covering Buttons Issue

Hey there! I see you're stuck with your animated video background blocking the 6 buttons you added via Interface Builder. Let's get those buttons visible again with two straightforward solutions.

Quickest Fix (No Extra IB Outlets Required)

The root problem here is that when you use addSublayer() to add your AVPlayerLayer to videoView's layer, this new layer gets placed on top of all existing subview layers (including the view that holds your buttons).

To fix this without needing to reference your buttons at all, just change how you insert the video layer—add it to the very bottom of videoView's layer stack instead:

  1. Open your ViewController.swift file
  2. In the setupView() function, replace this line:
    self.videoView.layer.addSublayer(newLayer)
    
    with:
    self.videoView.layer.insertSublayer(newLayer, at: 0)
    

This ensures the video layer sits underneath all of videoView's child views, so your buttons will automatically show up in front.

Alternative Fix (Adjusting the View Hierarchy)

If you prefer to explicitly bring your buttons to the front (maybe for clearer view hierarchy control), follow these steps:

  1. Open your Main.storyboard
  2. Locate the parent View that contains all 6 buttons (it's the child of your Video View)
  3. Control-drag from this parent view into your ViewController.swift file to create an IBOutlet. Name it something like buttonsContainerView:
    @IBOutlet weak var buttonsContainerView: UIView!
    
  4. In the setupView() function, add this line after you set up the video layer:
    self.videoView.bringSubviewToFront(self.buttonsContainerView)
    

This will force the button container view to sit on top of all other subviews in videoView, making your buttons visible over the video.

Full Modified Code (Using the Quick Fix)

Here's your complete ViewController code with the quick fix applied, plus some safer optional binding to avoid crashes:

import UIKit
import AVFoundation
import AVKit

class ViewController: UIViewController {
    @IBOutlet weak var videoView: UIView!

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

    private func setupView() {
        // Safely locate the video file without force-unwrapping
        guard let videoPath = Bundle.main.path(forResource: "Ocean_Waves_slow_motion_videvo", ofType: "mov"),
              let videoURL = URL(fileURLWithPath: videoPath) else {
            print("Error: Could not find the video file")
            return
        }

        let player = AVPlayer(url: videoURL)
        let playerLayer = AVPlayerLayer(player: player)
        
        playerLayer.frame = videoView.frame
        playerLayer.videoGravity = .resizeAspectFill
        
        // Insert video layer at the bottom of the layer stack
        videoView.layer.insertSublayer(playerLayer, at: 0)
        
        player.play()
        player.actionAtItemEnd = .none
        
        // Use the built-in notification name instead of a raw string
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(videoDidPlayToEnd(_:)),
            name: .AVPlayerItemDidPlayToEndTime,
            object: player.currentItem
        )
    }

    @objc func videoDidPlayToEnd(_ notification: Notification) {
        guard let playerItem = notification.object as? AVPlayerItem else { return }
        playerItem.seek(to: .zero)
    }
}

Either solution should work perfectly for your setup—pick whichever feels more intuitive for your project!

内容的提问来源于stack exchange,提问作者J. Wu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:50:51