Adding container view
This commit is contained in:
parent
b28f77a8ab
commit
b64927ebc2
@ -5,6 +5,9 @@ import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "YadUI",
|
||||
platforms: [
|
||||
.iOS(.v16)
|
||||
],
|
||||
products: [
|
||||
.library(name: "YadUI", targets: ["YadUI"]),
|
||||
],
|
||||
|
||||
69
Sources/YadUI/Views/ContainerView.swift
Normal file
69
Sources/YadUI/Views/ContainerView.swift
Normal file
@ -0,0 +1,69 @@
|
||||
//
|
||||
// ContainerView.swift
|
||||
//
|
||||
//
|
||||
// Created by Мустафаев Селим Мустафаевич on 01.08.2023.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import Combine
|
||||
|
||||
open class ContainerView: UIView {
|
||||
|
||||
private var body: UIView = UIView()
|
||||
public var cancellables: [AnyCancellable] = []
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
body = getBody()
|
||||
body.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(body)
|
||||
body.pin(to: self)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
@RootViewBuilder open func getBody() -> UIView {
|
||||
UIView()
|
||||
}
|
||||
}
|
||||
|
||||
extension UIView {
|
||||
|
||||
private func findContainer() -> ContainerView? {
|
||||
|
||||
var currentView: UIView = self
|
||||
while currentView.superview != nil {
|
||||
if currentView is ContainerView {
|
||||
return currentView as? ContainerView
|
||||
}
|
||||
currentView = currentView.superview!
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
public func bind<Src, SrcView, Dst, DstView>(_ prop: ReferenceWritableKeyPath<SrcView,Src>,
|
||||
to dstTag: Int,
|
||||
dstProp: KeyPath<DstView,Published<Dst>.Publisher>) -> Self where SrcView: UIView, Src: InitConvertible, Src.Param == Dst {
|
||||
|
||||
guard let container = findContainer(), let srcView = self as? SrcView else {
|
||||
return self
|
||||
}
|
||||
|
||||
guard let view = container.viewWithTag(dstTag) as? DstView else {
|
||||
return self
|
||||
}
|
||||
|
||||
let pub = view[keyPath: dstProp].map { Src($0) }
|
||||
pub.assign(to: prop, on: srcView)
|
||||
.store(in: &container.cancellables)
|
||||
|
||||
return self
|
||||
}
|
||||
}
|
||||
@ -22,8 +22,6 @@ public class Stack: UIView {
|
||||
|
||||
private var allConstraints: [NSLayoutConstraint] = []
|
||||
|
||||
private var cancellables: [AnyCancellable] = []
|
||||
|
||||
var dStart: NSLayoutConstraint.Attribute {
|
||||
axis == .vertical ? .top : .leading
|
||||
}
|
||||
@ -119,21 +117,4 @@ public class Stack: UIView {
|
||||
|
||||
addConstraint(src: lastView, srcAttr: dStart, dst: currentView, dstAttr: dEnd, constant: spacing)
|
||||
}
|
||||
|
||||
@available(iOS 16.0.0, *)
|
||||
public func bind<Src, Dst, U>(_ prop: ReferenceWritableKeyPath<Stack,Src>,
|
||||
to dstTag: Int,
|
||||
dstProp: KeyPath<U,Published<Dst>.Publisher>) -> Self where Src: InitConvertible, Src.Param == Dst {
|
||||
|
||||
// TODO: search relative to root view
|
||||
guard let view = viewWithTag(dstTag) as? U else {
|
||||
return self
|
||||
}
|
||||
|
||||
let pub = view[keyPath: dstProp].map { Src($0) }
|
||||
pub.assign(to: prop, on: self)
|
||||
.store(in: &cancellables)
|
||||
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
@ -22,15 +22,19 @@ extension Stack.Alignment: InitConvertible {
|
||||
|
||||
class ViewController: UIViewController {
|
||||
|
||||
let child = TestView()
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
let child = buildView()
|
||||
view.addSubview(child)
|
||||
child.pin(toSafeArea: view, insets: .init(all: 16))
|
||||
}
|
||||
}
|
||||
|
||||
@RootViewBuilder func buildView() -> UIView {
|
||||
class TestView: ContainerView {
|
||||
|
||||
override func getBody() -> UIView {
|
||||
VStack(alignment: .start, spacing: 16) {
|
||||
UILabel()
|
||||
.text("qwe")
|
||||
@ -45,7 +49,7 @@ class ViewController: UIViewController {
|
||||
YASegmentedControl(items: ["Left", "Center", "Right"])
|
||||
.tag(100)
|
||||
}
|
||||
.bind(\.alignment, to: 100, dstProp: \YASegmentedControl.$selectedIndex)
|
||||
.bind(\VStack.alignment, to: 100, dstProp: \YASegmentedControl.$selectedIndex)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user