【Swift UI】チャット機能の吹き出しViewを実装する方法!
この記事からわかること
- SwiftUIで吹き出しViewを実装する方法
- LINEやDMなどで活用されるメーセージView
- Path構造体の使い方
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
環境
- Xcode:15.0.1
- iOS:17.1
- Swift:5.9
- macOS:Sonoma 14.1
完成
チャット機能の吹き出しを実装する
Swift UIでLINEやDM(ダイレクトメール)のようなチャット機能で使われている吹き出しViewを実装するにはPath
構造体を使用します。
// 四角形の吹き出しUI
struct ChatView: Shape {
func path(in rect: CGRect) -> Path {
var path = Path()
// 左上の位置
path.move(to: CGPoint(x: rect.minX, y: rect.minY))
// 右上の位置
path.addLine(to: CGPoint(x: rect.maxX - 20, y: rect.minY))
// 三角形部分
path.addLine(to: CGPoint(x: rect.maxX - 20, y: rect.minY + 10))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
path.addLine(to: CGPoint(x: rect.maxX - 20, y: rect.minY + 40))
// 右下の位置
path.addLine(to: CGPoint(x: rect.maxX - 20, y: rect.maxY))
// 左下の位置
path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
path.closeSubpath()
return path
}
}
角に丸みを持たせたい場合は以下のように実装でいけました。
// 角丸の吹き出しUI
struct RoundChatView: Shape {
// 角の丸み
let radius: CGFloat = 10
func path(in rect: CGRect) -> Path {
var path = Path()
// 左上の角を丸める
path.move(to: CGPoint(x: rect.minX, y: rect.minY + radius))
path.addArc(center: CGPoint(x: rect.minX + radius, y: rect.minY + radius), radius: radius, startAngle: .degrees(180), endAngle: .degrees(270), clockwise: false)
// 右上の角を丸める
path.addLine(to: CGPoint(x: rect.maxX - radius - 20, y: rect.minY))
path.addArc(center: CGPoint(x: rect.maxX - radius - 20, y: rect.minY + radius), radius: radius, startAngle: .degrees(-90), endAngle: .degrees(0), clockwise: false)
// 三角形部分
path.addLine(to: CGPoint(x: rect.maxX - 20, y: rect.minY + 15))
path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
path.addLine(to: CGPoint(x: rect.maxX - 20, y: rect.maxY - 15))
// 右下の角を丸める
path.addLine(to: CGPoint(x: rect.maxX - 20, y: rect.maxY - radius))
path.addArc(center: CGPoint(x: rect.maxX - radius - 20, y: rect.maxY - radius), radius: radius, startAngle: .degrees(0), endAngle: .degrees(90), clockwise: false)
// 左下の角を丸める
path.addLine(to: CGPoint(x: rect.minX + radius, y: rect.maxY))
path.addArc(center: CGPoint(x: rect.minX + radius, y: rect.maxY - radius), radius: radius, startAngle: .degrees(90), endAngle: .degrees(180), clockwise: false)
path.closeSubpath()
return path
}
}
色を指定する際はbackground
ではpathで描画した以外の部分も変わってしまうのでfill
を使用します。
ChatView()
.fill(Color.gray)
.frame(width: 200, height: 50)
RoundChatView()
.fill(Color.gray)
.frame(width: 200, height: 50)
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。