mirror of
https://github.com/divkit/divkit.git
synced 2026-06-06 20:07:59 +00:00
144 lines
3.3 KiB
Swift
144 lines
3.3 KiB
Swift
import SwiftUI
|
|
import UIKit
|
|
|
|
import CommonCorePublic
|
|
import DivKit
|
|
import LayoutKit
|
|
|
|
struct SimpleDivView: UIViewRepresentable {
|
|
let cardId: DivCardID
|
|
let jsonData: Data?
|
|
let divKitComponents: DivKitComponents
|
|
|
|
func makeUIView(context _: Context) -> UIView {
|
|
SimpleDivUIView(
|
|
cardId: cardId,
|
|
jsonData: jsonData,
|
|
divKitComponents: divKitComponents
|
|
)
|
|
}
|
|
|
|
func updateUIView(_: UIView, context _: Context) {}
|
|
}
|
|
|
|
final class SimpleDivUIView: UIView {
|
|
private let cardId: DivCardID
|
|
private let jsonData: Data?
|
|
private let divKitComponents: DivKitComponents
|
|
|
|
private var divData: DivData?
|
|
private var block: Block = noDataBlock
|
|
|
|
private var blockView: BlockView! {
|
|
didSet {
|
|
if blockView !== oldValue {
|
|
oldValue?.removeFromSuperview()
|
|
addSubview(blockView)
|
|
}
|
|
}
|
|
}
|
|
|
|
init(
|
|
cardId: DivCardID,
|
|
jsonData: Data?,
|
|
divKitComponents: DivKitComponents
|
|
) {
|
|
self.cardId = cardId
|
|
self.jsonData = jsonData
|
|
self.divKitComponents = divKitComponents
|
|
|
|
super.init(frame: .zero)
|
|
|
|
if let jsonData = jsonData {
|
|
do {
|
|
divData = try divKitComponents
|
|
.parseDivDataWithTemplates(jsonData, cardId: cardId)
|
|
.unwrap()
|
|
} catch {
|
|
block = makeErrorBlock("\(error)")
|
|
}
|
|
}
|
|
|
|
update()
|
|
}
|
|
|
|
@available(*, unavailable)
|
|
required init?(coder _: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func layoutSubviews() {
|
|
super.layoutSubviews()
|
|
|
|
let blockSize = block.size(forResizableBlockSize: bounds.size)
|
|
blockView.frame = CGRect(origin: .zero, size: blockSize)
|
|
|
|
if bounds.size != blockSize {
|
|
invalidateIntrinsicContentSize()
|
|
}
|
|
}
|
|
|
|
override var intrinsicContentSize: CGSize {
|
|
block.size(forResizableBlockSize: bounds.size)
|
|
}
|
|
|
|
func update() {
|
|
if let divData = divData {
|
|
do {
|
|
block = try divData.makeBlock(
|
|
context: divKitComponents.makeContext(
|
|
cardId: cardId,
|
|
cachedImageHolders: block.getImageHolders(),
|
|
debugParams: AppComponents.debugParams
|
|
)
|
|
)
|
|
} catch {
|
|
block = makeErrorBlock("\(error)")
|
|
}
|
|
}
|
|
|
|
let elementStateObserver = divKitComponents.blockStateStorage
|
|
if let blockView = blockView, block.canConfigureBlockView(blockView) {
|
|
block.configureBlockView(
|
|
blockView,
|
|
observer: elementStateObserver,
|
|
overscrollDelegate: nil,
|
|
renderingDelegate: nil
|
|
)
|
|
} else {
|
|
blockView = block.makeBlockView(observer: elementStateObserver)
|
|
}
|
|
|
|
setNeedsLayout()
|
|
}
|
|
}
|
|
|
|
extension SimpleDivUIView: UIActionEventPerforming {
|
|
func perform(uiActionEvent event: UIActionEvent, from sender: AnyObject) {
|
|
perform(uiActionEvents: [event], from: sender)
|
|
}
|
|
|
|
func perform(uiActionEvents events: [UIActionEvent], from _: AnyObject) {
|
|
events.map { $0.payload }.forEach { handle($0) }
|
|
update()
|
|
}
|
|
|
|
private func handle(_ payload: UserInterfaceAction.Payload) {
|
|
switch payload {
|
|
case let .divAction(params):
|
|
divKitComponents.handleActions(params: params)
|
|
case .composite, .empty, .json, .menu, .url:
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
private let noDataBlock = EmptyBlock.zeroSized
|
|
|
|
private func makeErrorBlock(_ text: String) -> Block {
|
|
TextBlock(
|
|
widthTrait: .resizable,
|
|
text: text.withTypo(size: 18)
|
|
).addingEdgeGaps(20)
|
|
}
|