# TestFrameView

{% tabs %}
{% tab title="👔 TestFrameView" %}
⬆️ 需要： [.dimension](../../../view/.dimension "mention"), [.shadowedborder](../../../view/.shadowedborder "mention")

```swift
// 2022.02.14

import SwiftUI

struct TestFrameView: View {
    
    // view state
    @State private var offeredWidth: CGFloat = 50
    var width: Int { Int(offeredWidth) }    // integral width
    
    // view body
    var body: some View {
        VStack(spacing: 20) {
            
            // child views
            Group {
                
                // Texts
                Group {
                    // adaptive text
                    Text("an adaptive line of text that will try its best to fit the offered size.")
                    // text of "fixed" size
                    Text(#"a long line of text that is fixed at its "ideal width". "#)
                        // ⭐️ fixed at "ideal width"
                        .fixedSize(horizontal: true, vertical: false)
                }
                .foregroundColor(.secondary)
                .border(Color.blue)
                
                // ⭐️ a subview that'll always be wider than 100
                WiderThan100View()
                    // ⭐️ show child view's frame
                    // 🌀View+.dimension() (show frame visually)
                    .dimension(arrow: .blue, label: .yellow)
                    .overlay {
                        Text("\(width)").bold()
                            .shadow(radius: 4)
                    }
            }
            // ⭐️ parent's offered size
            .frame(width: offeredWidth, height: 60)
            .shadowedBorder()
            
            // slider
            VStack {
                Slider(value: $offeredWidth, in: 20...300, step: 1)
                    .padding(.horizontal)
                Text("offered width: \(width)")
                    .font(.system(.caption, design: .monospaced))
                    .foregroundColor(.secondary)
            }.padding(.top, 50)
        }
        .padding()
    }
}

/// a view that will always be wider than 100 points
struct WiderThan100View: View {
    var color: Color = .yellow
    var body: some View {
        // ⭐️ width >= 100
        color.frame(minWidth: 100)
    }
}
```
{% endtab %}

{% tab title="👁️ 預覽" %}
{% embed url="https://youtu.be/uEhDGOPHqaw" %}

```swift
struct TestFrameView_Previews: PreviewProvider {
    static var previews: some View {
        TestFrameView()
    }
}
```
{% endtab %}

{% tab title="⬆️ 需要" %}
* [.dimension](../../../view/.dimension "mention") - draw dimension for width.
* [.shadowedborder](../../../view/.shadowedborder "mention") - show frame's border.
{% endtab %}

{% tab title="📗 參考" %}
* [ ] SwiftUI Lab ⟩ [Frame Behaviors with SwiftUI](https://swiftui-lab.com/frame-behaviors/) ⭐️
{% endtab %}

{% tab title="📘 手冊" %}
* [.frame(minWidth:idealWidth:maxWidth ...)](https://developer.apple.com/documentation/swiftui/view/frame\(minwidth:idealwidth:maxwidth:minheight:idealheight:maxheight:alignment:\))
* [fixedSize()](https://developer.apple.com/documentation/swiftui/view/fixedsize\(\)), [fixedSize(horizontal:vertical:)](https://developer.apple.com/documentation/swiftui/view/fixedsize\(horizontal:vertical:\)) - fixed <mark style="color:red;">**ideal size**</mark>.
{% endtab %}

{% tab title="👥 相關" %}
* uses [.dimension](../../../view/.dimension "mention") ([view](../../../view "mention") extension) to show view's [frame]().
{% endtab %}
{% endtabs %}

## History

{% tabs %}
{% tab title="✏️" %}
1. 2022.02.14
{% endtab %}

{% tab title="1" %}
⬆️ 需要： [.dimension](../../../view/.dimension "mention"), [.clamped-in](../../../../../swift/type/category/protocol/comparable/.clamped-in "mention")

```swift
import SwiftUI

struct TestFrameView: View {
    
    // ⭐️ view state
    @State private var offeredWidth: CGFloat = 50
    var width: Int { Int(offeredWidth) }    // integral width
    
    // view body
    var body: some View {
        VStack(spacing: 50) {
            
            // ⭐️ child view
            childview(offeredWidth: offeredWidth)
            
                // ⭐️ child view's frame
                // 🌀View + .dimension(): show frame visually
                .dimension(arrow: .blue, label: .yellow)
                
                // ⭐️ parent's offered size
                .frame(width: offeredWidth, height: 100)
                
                .overlay {
                    Text("\(width)").bold()
                        .shadow(radius: 4)
                    Rectangle()
                        .stroke(lineWidth: 4)
                        .shadow(radius: 4)
                }

            // slider
            VStack {
                Slider(value: $offeredWidth, in: 20...200, step: 1)
                    .padding(.horizontal)
                Text("offered width: \(width)")
                    .font(.system(.caption, design: .monospaced))
                    .foregroundColor(.secondary)
            }
        }
        .padding()
    }
}

extension TestFrameView {
    /// ⭐️ child view for this demo
    func childview(offeredWidth width: CGFloat) -> some View {
        Color.yellow
            // 🌀 Comparable + .clamped(in:)
            .frame(width: offeredWidth.clamped(in: 100...))
    }
}
```
{% endtab %}
{% endtabs %}
