62500


SwiftUIで以下の画像のようなレイアウトを作りたいと思っています。  
そこで、Viewの左側は水色の太い線を、下側には細い灰色の線を引きたいのですが、border関数ではどうもできないようです。  
Viewの各辺にそれぞれ別の線を引く方法を教えて下さい。  
[![作りたいレイアウト](https://i.stack.imgur.com/supKF.jpg)](https://i.stack.imgur.com/supKF.jpg)


CC BY-SA 4.0
2020-01-20T05:49:21.057
62379
2020-01-28T02:13:53.160
22827
question
swift swift5 swiftui
Viewの各辺にそれぞれ別の線を引く


さて、ご自身でもいろいろ調べられたようですが、`border`では、辺を指定するような機能はないようです。文字通り自分で「線を引く」必要があるようです。

任意の線・図形を描くため、UIKitの`UIBezierPath`に相当するものとして、SwiftUIには`Path`なんてものがあります。

BorderedView.swift

[code]

    import SwiftUI
    
    struct BorderedView: View {
        var body: some View {
            ZStack(alignment: .leading) {
                //↓この部分を自分の表示したいViewに置き換え
                HStack {
                    Text("□")
                    Text("Text")
                }.padding(10)
                //↑
                BottomBorder(width: 1)
                    .foregroundColor(.gray)
                LeftBorder(width: 5)
                    .foregroundColor(.blue)
            }
        }
    }
    
    struct LeftBorder: Shape {
        var width: CGFloat
    
        func path(in rect: CGRect) -> Path {
            Path( CGRect(
                x: rect.minX,
                y: rect.minY,
                width: self.width,
                height: rect.height
            ) )
        }
    }
    struct BottomBorder: Shape {
        var width: CGFloat
    
        func path(in rect: CGRect) -> Path {
            Path( CGRect(
                x: rect.minX,
                y: rect.maxY - width,
                width: rect.width,
                height: self.width
            ) )
        }
    }
    
[/code]

ネタ元はこちらですが、あまり一般的に書くのもかえってわかりにくいかと思い、大幅に手を入れてあります。

[SwiftUI - Add Border to One Edge of an
Image](https://stackoverflow.com/a/58632759/6541007)

いろいろ突っ込みどころがあるかもしれませんが、ご自身で試してみて、より良いものができたら別解として投稿していただければと思います。


CC BY-SA 4.0
2020-01-23T22:41:50.060
62500
2020-01-23T22:41:50.060
13972
62379
answer


Rectangleを置いて幅や高さを調整して線に見せるといいですよ。  
1ptの線を引くなら高さまたは幅を1ptに指定した矩形を置く、ということです。

[code]

    struct ContentView: View {
        var body: some View {
            VStack {
                ForEach(1...10, id: \.self) { i in
                    VStack(spacing: 0) {
                        HStack {
                            Rectangle()
                                .foregroundColor(.blue)
                                .frame(width: 3) // 幅3pt, 高さ指定なし（幅3ptのタテの線）
                            RoundedRectangle(cornerRadius: 4)
                                .stroke(Color.gray)
                                .foregroundColor(.clear)
                                .frame(width: 20, height: 20)
                            Text("Test\(i)")
                            Spacer()
                        }
                        Rectangle()
                            .foregroundColor(.gray)
                            .frame(height: 1) // 幅指定なし, 高さ1pt（高さ1ptのヨコの線）
                    }
                }
            }
        }
    }
    
[/code]

[![画像の説明をここに入力](https://i.stack.imgur.com/4rSLx.png)](https://i.stack.imgur.com/4rSLx.png)


CC BY-SA 4.0
2020-01-24T16:10:17.447
62524
2020-01-24T16:10:17.447
5519
62379
answer


私が考えていた方法も書いておきます。  
Viewを塗りつぶし、横幅と縦幅を調整して線とする方法です。  
単純に線を入れるだけならこの方法がシンプルです。

ただ横幅を自動で最大にする方法が分かりませんでした。  
なので以下サンプルはwidthとheightに固定値を入れています。  
縦線のみだったらwidthの指定だけで済みます。

[code]

    HStack(spacing:0){
                Text("").frame(width: 2.0, height: 30).background(Color.blue)// 縦線
                VStack(spacing:0){
                    Spacer()
                    Text("").frame(width: 300, height: 1).background(Color.gray)// 横線
                }
            }.frame(width: 300, height: 30)
    
[/code]

[![コードの結果](https://i.stack.imgur.com/3qPWV.png)](https://i.stack.imgur.com/3qPWV.png)


CC BY-SA 4.0
2020-01-28T02:13:53.160
62598
2020-01-28T02:13:53.160
22827
62379
answer