【NOTE】SwiftUI中的数据流控制(一)各种State

这篇博客探讨了SwiftUI中数据流控制的关键概念,包括@State、@Binding、@AppStorage和@SceneStorage。@State用于控制视图更新,@Binding实现双向数据绑定,@AppStorage和@SceneStorage则提供了持久化的状态存储。文章详细阐述了它们的功能、用法以及在实际开发中的注意事项。
摘要由CSDN通过智能技术生成

NOTE \ SwiftUI中的数据流控制(一)各种State


SwiftUI会根据View(视图)中包含数据的变化自动刷新,因此其设计了多种Property Wrapper(属性包装器)来实现不同效果的状态控制。
@State @Binding @AppStorage @SceneStorage…

在这里插入图片描述

在SwiftUI中,用户的行为Action会改变UI的状态State,进而UI会更新与这种状态相关联的视图界面View。因此这种State起到控制视图变化的作用。


@State

创建一个可以控制视图变化的值类型变量

struct PlayerView: View {
   
    var episode: Episode
    @State private var isPlaying: Bool = false

    var body: some View {
   
        VStack {
   
            Text(episode.title)
            Text(episode.showTitle)
            PlayButton(isPlaying: $isPlaying)
        }
    }
}//来自AppleDocumentation

功能

@State isPlaying使得SwiftUI会在isPlaying改变后刷新本视图(PlayerView)中所有与isPlaying相关的UI。若不加@State包装器,此时isPlaying值的变化都不会引起UI的变化,只有通过某些手段刷新视图后才能看到相应的改变。

在上面的代码中,playButton的状态会跟随isPlaying 值一起变化。其中 $isplaying使得playButton这个子视图可以动态获得并且修改isPlaying的值。

结构

当使用 @State来包装isPlaying 时,实际上产生了

  1. 包含wrappedValue和projectedValue两个值的结构体_isPlaying

    • wrappedValue: Bool
    • projectedValue: Binding<Bool>
  2. 原名称前添加‘ ’ 前 缀 的 ∗ ∗ ’前缀的 **

In SwiftUI, you can use the `AVCaptureSession` and `AVCaptureVideoPreviewLayer` classes from the AVFoundation framework to record videos. Here's an example of how you can do it: ```swift import SwiftUI import AV struct ContentView: View { @State private var isRecording = false let captureSession = AVCaptureSession() let movieOutput = AVCaptureMovieFileOutput() var body: some View { VStack { if !isRecording { Button("Record") { startRecording() } } else { Button("Stop") { stopRecording() } } } .onAppear { setupCamera() } } func setupCamera() { let captureDevice = AVCaptureDevice.default(for: .video) guard let input = try? AVCaptureDeviceInput(device: captureDevice!) else { return } guard captureSession.canAddInput(input) else { return } captureSession.addInput(input) guard captureSession.canAddOutput(movieOutput) else { return } captureSession.sessionPreset = .high captureSession.addOutput(movieOutput) let previewLayer = AVCaptureVideoPreviewLayer(session: captureSession) previewLayer.videoGravity = .resizeAspectFill let rootLayer = NSView(frame: NSRect(x: 0, y: 0, width: 300, height: 300)) rootLayer.wantsLayer = true rootLayer.layer?.backgroundColor = NSColor.black.cgColor rootLayer.layer?.addSublayer(previewLayer) previewLayer.frame = rootLayer.bounds let uiView = NSHostingView(rootView: rootLayer) uiView.frame = CGRect(x: 0, y: 0, width: 300, height: 300) let viewController = NSViewController() viewController.view = uiView let window = NSWindow(contentViewController: viewController) window.makeKeyAndOrderFront(nil) captureSession.startRunning() } func startRecording() { let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask) let fileUrl = paths[0].appendingPathComponent("output.mov") movieOutput.startRecording(to: fileUrl, recordingDelegate: self) isRecording = true } func stopRecording() { movieOutput.stopRecording() isRecording = false } } extension ContentView: AVCaptureFileOutputRecordingDelegate { func fileOutput(_ output: AVCaptureFileOutput, didStartRecordingTo fileURL: URL, from connections: [AVCaptureConnection]) { print("Started recording to \(fileURL)") } func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) { print("Finished recording to \(outputFileURL)") } } ``` This example sets up a camera preview using `AVCaptureVideoPreviewLayer` and records a video when the "Record" button is tapped. The recorded video is saved to the document directory with the name "output.mov". The recording can be stopped by tapping the "Stop" button. Please note that this code is for macOS development using SwiftUI. If you want to record videos in SwiftUI for iOS, you will need to make some modifications.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值