質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

1回答

1216閲覧

swiftの表記をSwiftUIで表現したい。初心者

Bakemoon

総合スコア1

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2021/09/20 05:12

Websiteで見つけた、Imageを多角形にする方法を
SwiftUIで落とし込んでも"Cannot find 'imageview' in scope"のエラーが出ます。

import SwiftUI
import UIKit

extension UIImageView {

func clipToPolygon(corners: Int) { guard corners >= 3 else { print("(#file)(#function) corerns must be >= 3") return } let radius = min(self.frame.width/2.0,self.frame.height/2.0) let center = CGPoint(x:self.bounds.width/2.0,y:self.bounds.height/2.0) let path = UIBezierPath() path.lineWidth = 1 for index in 0...corners { let rad = (Double.pi / Double(corners) ) * Double(index * 2 + 1) print(rad * 180 / Double.pi) let drawPoint = CGPoint(x: center.x + radius * CGFloat(cos(rad)), y: center.y + radius * CGFloat(sin(rad))) if (index == 0) { path.move(to: drawPoint) } else if (index == corners ) { path.close() } else { path.addLine(to: drawPoint) } } let mask = CAShapeLayer() mask.path = path.cgPath self.layer.mask = mask self.layer.masksToBounds = false }

}

struct ContentView: View {
var body: some View {

imageview.clipToPolygon(corners:6)

//ここでエラー

}

}

お力を貸してください。

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2021/09/24 10:14

回答について全く無反応ですがどうされたのでしょうか
guest

回答1

0

SwiftUIで6角形を作りたい。」の内容をふまえると、UIImageView のエクステンションを SwiftUI と統合したいというより、画像を六角形でくりぬくのが目的なのでしょうか?

画像に対して .clipShape() を使い、好きな形のシェイプをわたせばその形にくりぬくことができます。前述の質問で作った Hexagon シェイプがあるなら、次のようにして正六角形にくりぬけます。

swift

1struct ContentView: View { 2 var body: some View { 3 Image("Sample") 4 .resizable() 5 .aspectRatio(contentMode: .fill) 6 .clipShape(Hexagon()) 7 } 8}

イメージ説明


これが、ブラー効果を画像にかけながらその効果を正六角形でくりぬきたいとなると少し難しくなります。SwiftUI ではブラー効果自体は .blur でかんたんにかけられますが、その効果範囲だけをシェイプでくりぬくことができません。

swift

1struct ContentView: View { 2 var body: some View { 3 Image("Sample") 4 .resizable() 5 .aspectRatio(contentMode: .fill) 6 .blur(radius: 5, opaque: true) 7 // .clipShape(Hexagon()) を追加してもブラーのかかった画像全体をくりぬいてしまう 8 } 9}

ZStack を使ってブラーのかかった画像とくりぬいた画像を重ねるのも一つの手ですが、スマートではないです。

swift

1struct ContentView: View { 2 var body: some View { 3 ZStack { 4 Image("Sample") 5 .resizable() 6 .aspectRatio(contentMode: .fill) 7 .blur(radius: 50, opaque: true) 8 9 Image("Sample") 10 .resizable() 11 .aspectRatio(contentMode: .fill) 12 .clipShape(Hexagon()) 13 } 14 } 15}

そこで、UIKit に用意された効果そのもののビュー UIVisualEffectView を SwiftUI に統合し、そのビューをくりぬくようにします。

UIKit のビューを SwiftUI で使うには UIViewRepresentable プロトコルを使って構造体を作ります。

基本的には makeUIView() メソッドで UIKit のビューを作って返し、updateUIView で状態を更新します。いちばんかんたんな作り方としては、そのクラス特有のプロパティの値だけ仲介してセットするようにすればいいです。

よく分からなければ今はコピペでもかまいません。

swift

1struct VisualEffectView<T: UIVisualEffectView>: UIViewRepresentable { 2 var effect: UIVisualEffect? 3 func makeUIView(context: UIViewRepresentableContext<Self>) -> T { 4 T() 5 } 6 func updateUIView(_ uiView: T, context: UIViewRepresentableContext<Self>) { 7 uiView.effect = effect 8 } 9}

これで VisualEffectView というビューが SwiftUI で使えます。これを使って、画像の上にブラー効果を重ね、それをうまくくりぬいて真ん中だけ効果がかからないようにします。

全体としては次のようになります。

swift

1import SwiftUI 2import UIKit 3 4struct ContentView: View { 5 var body: some View { 6 ZStack { 7 Image("Sample") 8 .resizable() 9 .aspectRatio(contentMode: .fill) 10 11 VisualEffectView(effect: UIBlurEffect(style: .regular)) 12 .mask( 13 ZStack(alignment: .center) { 14 Color.white 15 Hexagon().foregroundColor(.black) 16 } 17 .compositingGroup() 18 .luminanceToAlpha() 19 ) 20 } 21 } 22} 23 24struct VisualEffectView<T: UIVisualEffectView>: UIViewRepresentable { 25 var effect: UIVisualEffect? 26 func makeUIView(context: UIViewRepresentableContext<Self>) -> T { 27 T() 28 } 29 func updateUIView(_ uiView: T, context: UIViewRepresentableContext<Self>) { 30 uiView.effect = effect 31 } 32}

イメージ説明


ここからは興味があれば読むくらいでかまいませんが、以下のコードの役割はそれぞれこのようなになります。

swift

1.mask( 2 ZStack(alignment: .center) { 3 Color.white // 全体を覆う白いビュー 4 Hexagon().foregroundColor(.black) // 正六角形の黒いシェイプ 5 } 6 .compositingGroup() // ZStack の中身をひとつのレイヤととらえて合成するためにグループ化 7 .luminanceToAlpha() // 黒い部分を透明に、白い部分を不透明にする 8)

.luminanceToAlpha() という黒い部分ほど透明にする効果を使うために、全体を覆うビューとシェイプで白黒画像を作っています。

投稿2021/09/22 00:10

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問