3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

SwiftUIプロダクトにリンク機能を実装~UIViewRepresentable~

Posted at

はじめに

下記の画像のように個人開発のアプリで、ユーザーの投稿内容にURLが含まれていた場合、それを検知し、リンク先に飛ぶことができるようにするリンク機能を実装しました。その機能を実装する中でSwiftUIの足りないところをUIViewRepresentableを使用し、UIKitで補う必要があったのでそこで学んだ内容を紹介したいと思います。

アップデート前 アップデート後
IMG_5057.PNG IMG_5055.PNG

UIViewRepresentableとは

SWiftUIのViewでUIKitを使用することができるようにするWrapper

// Protocol
public protocol UIViewRepresentable : View where Self.Body == Never {
    // どの型のUIViewをラップするか
    associatedtype UIViewType: UIView
    // ラップするUIViewのインスタンスを作って返す
    func makeUIView(context: Self.Context) -> Self.UIViewType
    // データの更新に応じてラップしているUIViewを更新
    func updateUIView(_ uiView: Self.UIViewType, context: Self.Context)
}

UIViewRepresentableを使用してSwiftUIでは足りないところをUIKitで補う

リンク機能を実装するためにUIKitの下記のUITextViewクラスを使用しました。

上記のメソッドを使用し、TextViewWrapper構造体を作成する

TextViewWrapper.swift
import SwiftUI

struct TextViewWrapper: UIViewRepresentable {
    // 受け取りたいデータをプロパティとして定義
    let text: String
    // UIViewType のインスタンスを生成して返す
    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        // 読み取り専用
        textView.isEditable = false
        // Linkを指定
        textView.dataDetectorTypes = .link
        // リンクの色を指定する
        textView.linkTextAttributes = [.foregroundColor: UIColor.systemBlue]
        textView.font = UIFont.systemFont(ofSize: 16)
        return textView
    }
    // UIViewを更新
    func updateUIView(_ textView: UITextView, context: Context) {
        textView.text = text
    }
}

isEditableはデフォルトでtrueであるが、今回は読み取り専用なのでfalseにする。
dataDetectorTypes URLに自動的に変換するデータのタイプを指定する。
linkTextAttributesでリンクの色を青色に指定します。
fontで本当の大きさを指定。

上記で作成したTextViewWrapperをView側で使用例

PostView.swift
          HStack {
                Button {
                    isPostImageViewShowing = true
                } label: {
                    Image(uiImage: postImage)
                        .resizable()
                        .scaledToFill()
                        .frame(width: 100, height: 100, alignment: .center)
                        .clipShape(RoundedRectangle(cornerRadius: 20))
                        .padding(.horizontal, 10)
                }
                TextViewWrapper(text: post.caption)
            }

上記の手順で実装することで、アップデートでリンク機能の実装、文字選択機能の実装ができました。

リンク機能 文字選択
IMG_5055.PNG IMG_5056.PNG

参考文献

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?