View - Tai-Kimura/SwiftJsonUI GitHub Wiki
View
class: SJUIView inherits: UIView child classes: [GradientView](/Tai-Kimura/SwiftJsonUI/wiki/GradientView), [SJUISelectBox](/Tai-Kimura/SwiftJsonUI/wiki/SelectBox)
Platform Support
- ✅ UIKit: Full support (All attributes available)
- ✅ SwiftUI: Full support (All attributes available through DynamicComponent)
- SafeAreaView maps to SwiftUI's native safe area handling
- ✅ Jetpack Compose: Full support (Maps to Box/Column/Row based on orientation)
- ✅ Android XML: Maps to
LinearLayout(with orientation) orConstraintLayout(without orientation)- View with
orientation: "horizontal"→LinearLayout(horizontal) - View with
orientation: "vertical"→LinearLayout(vertical) - View without orientation →
ConstraintLayout - SafeAreaView →
com.kotlinjsonui.views.KjuiSafeAreaView
- View with
Attributes for View
| attribute name | UIKit | SwiftUI | Compose | XML | type in json | details | remarks |
|---|---|---|---|---|---|---|---|
| orientation | ✅ | ✅ | ✅ | ✅ | string | View orientation: vertical, horizontal. Behaves like Linear Layout | XML: android:orientation |
| direction | ✅ | ✅ | ✅ | ❌ | string | Layout direction: topToBottom, bottomToTop, leftToRight, rightToLeft | |
| gravity | ✅ | ✅ | ✅ | ✅ | string | Content gravity: top, bottom, centerVertical, left, right, centerHorizontal | XML: android:gravity |
| highlightBackground | ✅ | ✅ | ❌ | ❌ | string | Background color when highlighted | Dynamic mode only |
| highlighted | ✅ | ✅ | ❌ | ❌ | boolean | View highlighted state | Dynamic mode only |
| canTap | ✅ | ✅ | ✅ | ✅ | boolean | Enable tap capability. Prevents background color change when false | XML: android:clickable |
| tapBackground | ✅ | ✅ | ❌ | ✅ | string | Background color when tapped | XML: selector drawable |
| onclick | ✅ | ✅ | ✅ | ✅ | string | Tap gesture selector | XML: android:onClick |
| onClick | ✅ | ✅ | ✅ | ✅ | string | Closure-based tap handler ((UITapGestureRecognizer) -> Void) | XML: android:onClick |
| onLongPress | ✅ | ✅ | ✅ | ❌ | string | Long press closure handler | |
| onPan | ✅ | ✅ | ❌ | ❌ | string | Pan gesture closure handler | |
| onPinch | ✅ | ✅ | ❌ | ❌ | string | Pinch gesture closure handler | |
| events | ✅ | ✅ | ❌ | ❌ | dictionary | Complex event handlers with multiple gesture types | Dynamic mode only |
| touchDisabledState | ✅ | ✅ | ❌ | ❌ | string | Touch handling control: none, onlyMe, viewsWithoutTouchEnabled, viewsWithoutInList | Dynamic mode only |
| touchEnabledViewIds | ✅ | ✅ | ❌ | ❌ | array | List of view IDs that remain touch-enabled | Dynamic mode only |
| safeAreaInsetPositions | ✅ | ✅ | ✅ | ✅ | array | SafeAreaView edges: ["all"], ["top", "bottom"], etc. | SafeAreaView only; XML: KjuiSafeAreaView |
| shadow | ✅ | ✅ | ✅ | ✅ | JSON | Shadow configuration with color, offset, radius, opacity | XML: android:elevation |
| clipToBounds | ✅ | ✅ | ✅ | ✅ | boolean | Clip content to bounds | XML: android:clipChildren |
| userInteractionEnabled | ✅ | ✅ | ✅ | ✅ | boolean | Enable user interaction | XML: android:enabled |
| semanticContentAttribute | ✅ | ❌ | ❌ | ❌ | string | RTL/LTR layout direction | UIKit only |
Properties for View
open class var viewClass: SJUIView.Type
this property will be used to decide which class to inflate with createFromJSON method. You should define the view's class on this property when you create classes inherite SJUIView.
open class var canTap: Bool
Explanation is in Attributes table.
open class var highlighted: Bool
Explanation is in Attributes table.
open class var orientation: SJUIView.Orientation
Explanation is in Attributes table. You should call resetConstraintInfo method to apply view's constraint after changing this property.
open class var direction: SJUIView.Direction
Explanation is in Attributes table. You should call resetConstraintInfo method to apply view's constraint after changing this property.
open class var gravity: SJUIView.Gravity
Explanation is in Attributes table. You should call resetConstraintInfo method to apply view's constraint after changing this property.
Functions for View
open override func didAddSubview(_ subview: UIView)
inherited from UIView. this method will call when subview is added. resetConstraintInfo will call when this method is called.
public func addSubViewWith(json: JSON, target: Any, withCreatorClass creator: SJUIViewCreator.Type = SJUIViewCreator.self)
Use this method when you want to add subview created from json file from code.
public class func createFromJSON(attr: JSON, target: Any, views: inout [String: UIView]) -> SJUIView
This method will be called when it's created from json file. Override This method when you create classes inherite SJUIView class.
TouchDisabledState Implementation Examples
Example 1: Basic touchDisabledState Usage
{
"type": "View",
"id": "container",
"width": "matchParent",
"height": "matchParent",
"touchDisabledState": "onlyMe",
"background": "#CCCCCC",
"child": [
{
"type": "Button",
"id": "button1",
"width": 100,
"height": 50,
"text": "Clickable",
"onclick": "buttonTapped"
}
]
}
In this example, the container view cannot be tapped, but the button inside remains clickable.
Example 2: Using touchEnabledViewIds
{
"type": "View",
"id": "parentView",
"width": "matchParent",
"height": "matchParent",
"touchDisabledState": "viewsWithoutInList",
"touchEnabledViewIds": ["allowedButton", "allowedLabel"],
"background": "#EEEEEE",
"child": [
{
"type": "Button",
"id": "allowedButton",
"width": 120,
"height": 50,
"text": "Allowed",
"onclick": "allowedButtonTapped"
},
{
"type": "Button",
"id": "blockedButton",
"width": 120,
"height": 50,
"text": "Blocked",
"onclick": "blockedButtonTapped"
},
{
"type": "Label",
"id": "allowedLabel",
"width": "wrapContent",
"height": "wrapContent",
"text": "Clickable Label",
"onclick": "labelTapped"
}
]
}
Only "allowedButton" and "allowedLabel" will receive touch events. "blockedButton" will not respond to touches.
Example 3: Conditional Touch Enabling with Data Binding
{
"type": "View",
"id": "conditionalView",
"width": "matchParent",
"height": 200,
"data": [
{
"name": "isInteractionEnabled",
"class": "Bool",
"defaultValue": true
},
{
"name": "enabledViewIds",
"class": "[String]",
"defaultValue": []
}
],
"touchDisabledState": "@{isInteractionEnabled ? 'none' : 'viewsWithoutInList'}",
"touchEnabledViewIds": "@{enabledViewIds}",
"background": "#F0F0F0",
"child": [
{
"type": "Button",
"id": "controlButton",
"width": 150,
"height": 50,
"text": "Toggle Interaction",
"onclick": "toggleInteraction"
},
{
"type": "Button",
"id": "actionButton",
"width": 120,
"height": 50,
"text": "Action",
"onclick": "performAction"
}
]
}
This example shows how to dynamically control touch behavior using data binding.
Swift Implementation Example
class ViewController: UIViewController {
@IBOutlet weak var containerView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
setupTouchControlledView()
}
func setupTouchControlledView() {
let jsonString = """
{
"type": "View",
"id": "touchControlledContainer",
"width": "matchParent",
"height": 300,
"touchDisabledState": "viewsWithoutInList",
"touchEnabledViewIds": ["enabledButton"],
"background": "#E8E8E8",
"child": [
{
"type": "Button",
"id": "enabledButton",
"width": 140,
"height": 50,
"text": "Enabled",
"onclick": "enabledButtonTapped"
},
{
"type": "Button",
"id": "disabledButton",
"width": 140,
"height": 50,
"text": "Disabled",
"onclick": "disabledButtonTapped"
}
]
}
"""
if let jsonData = jsonString.data(using: .utf8),
let json = try? JSON(data: jsonData) {
let createdView = SJUIViewCreator.viewFromJSON(json, target: self)
containerView.addSubview(createdView)
createdView.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
createdView.topAnchor.constraint(equalTo: containerView.topAnchor),
createdView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
createdView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
createdView.heightAnchor.constraint(equalToConstant: 300)
])
}
}
@objc func enabledButtonTapped() {
print("Enabled button was tapped")
}
@objc func disabledButtonTapped() {
print("This will not be called due to touchDisabledState")
}
}
Dynamic touchDisabledState Control
Currently, touchDisabledState can be controlled dynamically using data binding syntax @{}, but there is no specific handler implementation in binding_builder for this attribute. If you need to change touchDisabledState dynamically from Swift code, you would need to:
- Access the view directly and modify the property:
if let containerView = view.findViewWithId("container") as? SJUIView {
containerView.touchDisabledState = .viewsWithoutInList
containerView.touchEnabledViewIds = ["newAllowedButton"]
}
- Use invalidate methods to refresh the layout after changes:
// After modifying touchDisabledState or touchEnabledViewIds
containerView.setNeedsLayout()
containerView.layoutIfNeeded()
- Consider adding custom handler support:
# This could be added to view_binding_handler.rb in the future:
when "touchDisabledState"
@binding_content << " #{view_name}?.touchDisabledState = TouchDisabledState(rawValue: #{value}) ?? .none\n"
true
when "touchEnabledViewIds"
@binding_content << " #{view_name}?.touchEnabledViewIds = #{value}\n"
true
Note: For full dynamic control through binding_builder, custom handler implementation would be needed in the view_binding_handler.rb file.