Swift

フルスクリーンキャプチャのためのルートビューの露出

アプリの画面全体をキャプチャするには、ルートにアクセスする必要があります。 UIView.拡張子を追加する:

UIApplication+rootViewController.swift

import UIKit

extension UIApplication {
    var rootViewController: UIViewController? {
        connectedScenes
            .compactMap { $0 as? UIWindowScene }
            .flatMap { $0.windows }
            .first { $0.isKeyWindow }?
            .rootViewController
    }
}

それなら、これを使おう:

guard let rootView = UIApplication.shared.rootViewController?.view else { return }
capturer = ScreenCapturer(withView: rootView)

代替パスUIViewRepresentableで特定の領域をキャプチャする

以下のステップでは、ScreenCapturerにrootViewを配線する方法を紹介します。ただし、画面の特定の領域をキャプチャしたい場合は、特定の UIView SwiftUIに支えられた作成する UIViewRepresentable 共有したいビューを生成し、それをレイアウトに埋め込み、その基礎となる UIView をキャプチャーに送る(たとえば、次のような場合にコールバックを介して)。 makeUIView 走る)。

例-共有可能なタイムラベル:

import SwiftUI
import UIKit

struct TimeLabelView: UIViewRepresentable {
    let text: String
    private let labelTag = 1001

    func makeUIView(context: Context) -> UIView {
        let container = UIView()
        container.backgroundColor = .red

        let label = UILabel()
        label.tag = labelTag
        label.textAlignment = .center
        label.backgroundColor = .clear
        label.textColor = .white
        label.adjustsFontSizeToFitWidth = true

        label.translatesAutoresizingMaskIntoConstraints = false
        container.addSubview(label)

        NSLayoutConstraint.activate([
            label.leadingAnchor.constraint(equalTo: container.leadingAnchor),
            label.trailingAnchor.constraint(equalTo: container.trailingAnchor),
            label.topAnchor.constraint(equalTo: container.topAnchor),
            label.bottomAnchor.constraint(equalTo: container.bottomAnchor)
        ])

        return container
    }

    func updateUIView(_ uiView: UIView, context: Context) {
        (uiView.viewWithTag(labelTag) as? UILabel)?.text = text
    }
}

ディスプレイ TimeLabelView をSwiftUIの UIView をマネージャーに送る。 @State そして onAppear / Coordinator)、そのビューを ScreenCapturer(withView:) をクリックすると、全画面ではなくその領域だけを共有することができます。