SwiftUIでインタースティシャル広告を実装する方法
インタースティシャル用のクラスを用意
import GoogleMobileAds
#if DEBUG
let adUnitID = ""
#else
let adUnitID = ""
#endif
final class Interstitial: NSObject, GADFullScreenContentDelegate {
private var interstitial: GADInterstitialAd?
override init() {
super.init()
loadInterstitial()
}
func loadInterstitial(){
let request = GADRequest()
GADInterstitialAd.load(withAdUnitID:adUnitID,
request: request,
completionHandler: { [self] ad, error in
if let error = error {
print("Failed to load interstitial ad: \(error.localizedDescription)")
return
}
interstitial = ad
interstitial?.fullScreenContentDelegate = self
}
)
}
/// Tells the delegate that the ad failed to present full screen content.
func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) {
print("Ad did fail to present full screen content.")
}
/// Tells the delegate that the ad presented full screen content.
func adDidPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) {
print("Ad did present full screen content.")
}
/// Tells the delegate that the ad dismissed full screen content.
func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) {
print("Ad did dismiss full screen content.")
loadInterstitial()
}
func showAd(){
let root = UIApplication.shared.windows.first?.rootViewController
interstitial?.present(fromRootViewController: root!)
}
}
SWiftuiのボタン押下時に呼び出し
変数は用意してください
//保存ボタン
Button(action:{
self.showingAlert = true
}){
Image(systemName: "tray.and.arrow.down")
Text("保存")
}
.padding(.trailing)
.alert(isPresented: $showingAlert) {
Alert(title: Text("保存しますか"),
primaryButton: .cancel(Text("キャンセル")),
secondaryButton: .default(Text("保存"),
action: {
interstitial.showAd()
}))
}
【Swift UI】配列を特定の文字で絞り込む方法
ちょっとだけ詰まったので載せておきます。
Textfieldに入力された文字でLISTの絞りこみをしたかったので実装しました。
こんな感じです。


リストは配列をループさせて表示しているので、Textfield入力された文字で配列を絞り込めば上記が実現できます。
nameがテキストフィールドの値でitemが配列です。
絞り込まれた配列はsearchArray の中に入ります。
ContentView一部抜粋
self.searchArray = item.filter{
if $0.localizedCaseInsensitiveContains(name){
return true
}
return false
}
ContentView.Swift
//
// ContentView.swift
// olnpickGolfer
//
// Created by Yosuke Yoshida on 2021/02/09.
//
import SwiftUI
struct ContentView: View {
@State private var name:String = ""
@State private var item = getDataName()
@State private var isShowingAlert = false
@State private var showingAlert = false
@State var text: String = ""
@State private var selectionValue: Set<String>
= []
@State var searchArray = [String]()
var body: some View {
VStack {
TextField("検索", text: $name,onCommit: {
item = getDataName()
if self.name == "" {
item = getDataName()
} else {
self.searchArray = item.filter{
if $0.localizedCaseInsensitiveContains(name){
return true
}
return false
}
item = searchArray
}
})
.padding()
// 入力域のまわりを枠で囲む
.textFieldStyle(RoundedBorderTextFieldStyle())
List (selection: $selectionValue) {
ForEach(item, id: \.self) { item in
Text(item)
}
}
.environment(\.editMode, .constant(.active))
Spacer()
HStack {
Button("追加") { isShowingAlert = true }
.padding()
if !item.isEmpty {
Button("削除") {
rowRemove(delList: selectionValue)
selectionValue = []
}
.padding()
}
Spacer()
TextFieldAlertView(
text: $text,
isShowingAlert: $isShowingAlert,
placeholder: "",
isSecureTextEntry: false,
title: "名前登録",
message: "名前を入力してください",
leftButtonTitle: "キャンセル",
rightButtonTitle: "登録",
leftButtonAction: nil,
rightButtonAction: {
if item.contains(text) {
alertD()
} else {
registDataName(name: text)
item = getDataName()
}
}
)
.frame(width: 0, height: 0, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
}
}
}
func rowRemove(delList:Set<String>) {
var counter:Int = 0
var isDel = false
var tmpItem = getDataName()
while counter < tmpItem.count {
for data in delList {
if tmpItem[counter] == data {
tmpItem.remove(at: counter)
isDel = true
}
}
if isDel {
counter = 0
isDel = false
} else {
counter+=1
}
}
reWriteDataName(nameList: tmpItem)
item = getDataName()
self.name = ""
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
【Swift UI】初期起動画面を変更する方法
SceneDelegate.swift
let contentView = SwiftUIView()ここの値を起動したいViewの名前に変更してください。
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
// Create the SwiftUI view that provides the window contents.
let contentView = SwiftUIView()//ここの値を起動したいViewの名前に変更する。
// Use a UIHostingController as window root view controller.
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
window.rootViewController = UIHostingController(rootView: contentView)
self.window = window
window.makeKeyAndVisible()
}
}
【Swift UI】LISTが複数選択と削除が同居できない
Swift UIのリストについての記事です。
UserDefaultに保存されているデータをLISTに表示させ、選択できるような画面を作成しました。
ついでに削除までできたら便利だなぁと考えて調べてみましが、両立させることができませんでした。
最終的にはかなりの力技で実装しました。誰か知ってたら教えて欲しいものです。
①複数選択を可能にする。
→できる。

ContentView.swiftの一部
List (selection: $selectionValue) {
ForEach(item, id: \.self) { item in
Text(item)
}
}
<u> .environment(\.editMode, .constant(.active))</u>②削除可能
→できる。
左にスワイプしたら削除ボタンが出てきます。

List (selection: $selectionValue) {
ForEach(item, id: \.self) { item in
Text(item)
}
/// 行削除操作時に呼び出す処理の指定
.onDelete(perform: rowRemove)
}③両立
→色々調べたが、できない。
選択はできるが、スライドしても削除ボタンが出てこない。。
List (selection: $selectionValue) {
ForEach(item, id: \.self) { item in
Text(item)
}
/// 行削除操作時に呼び出す処理の指定
.onDelete(perform: rowRemove)
}
.environment(\.editMode, .constant(.active))解決策としては、削除ボタンとリストから削除する処理を自前で実装して、乗り越えました。
//
// ContentView.swift
// olnpickGolfer
//
// Created by Yosuke Yoshida on 2021/02/09.
//
import SwiftUI
struct ContentView: View {
@State private var name = ""
@State private var item = getDataName()
@State private var isShowingAlert = false
@State private var showingAlert = false
@State var text: String = ""
@State private var selectionValue: Set<String>
= []
var body: some View {
VStack {
TextField("検索", text: $name)
.padding()
// 入力域のまわりを枠で囲む
.textFieldStyle(RoundedBorderTextFieldStyle())
List (selection: $selectionValue) {
ForEach(item, id: \.self) { item in
Text(item)
}
}
.environment(\.editMode, .constant(.active))
Spacer()
HStack {
Button("追加") { isShowingAlert = true }
.padding()
if !item.isEmpty {
Button("削除") {
rowRemove(delList: selectionValue)
selectionValue = []
}
.padding()
}
Spacer()
TextFieldAlertView(
text: $text,
isShowingAlert: $isShowingAlert,
placeholder: "",
isSecureTextEntry: false,
title: "名前登録",
message: "名前を入力してください",
leftButtonTitle: "キャンセル",
rightButtonTitle: "登録",
leftButtonAction: nil,
rightButtonAction: {
if item.contains(text) {
alertD()
} else {
registDataName(name: text)
item = getDataName()
}
}
)
.frame(width: 0, height: 0, alignment: /*@START_MENU_TOKEN@*/.center/*@END_MENU_TOKEN@*/)
}
}
}
func rowRemove(delList:Set<String>) {
var counter:Int = 0
var isDel = false
while counter < item.count {
for data in delList {
if item[counter] == data {
item.remove(at: counter)
isDel = true
}
}
if isDel {
counter = 0
isDel = false
} else {
counter+=1
}
}
reWriteDataName(nameList: item)
item = getDataName()
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
SwiftUIでは入力ダイアログはサポートされない件
2019年6月から開始されたSwiftUIですが、触ってみた感じ、かゆいところに手が届かないなぁと思いました。
発端は、入力ダイアログを使おうと思って、調べてみたらSwift UIではAlert表示はできるが、ユーザーから入力させるよなテキストフィールドは追加できないとのこと。
うーん。
SwiftUIで完結できると記載されている記事をありましたが、エラーになってしまいうまく動きませんでした。
面倒なので、エラー内容を追うことはしませんでした。m(__)m↓↓
alert — SwiftUIでTextFieldをAlertに追加する方法は?
解決策としては、
UIViewControllerRepresentable プロトコルを継承して、UKit の UIAlertController をラップしたViewを作成することで実装すれば良いとのこと。
下記サイトに記載されているコードを完コピで動きました。
【SwiftUI】TextField付きAlertを表示する – .NET ゆる〜りワーク
ただし、TextFieldAlertViewが要素の一部として認識されてしまい、レイアウトが崩れてしまうので、サイズを0にすることで解決しました。
TextFieldAlertView(
text: $text,
isShowingAlert: $isShowingAlert,
placeholder: "",
isSecureTextEntry: false,
title: "名前登録",
message: "名前を入力してください",
leftButtonTitle: "キャンセル",
rightButtonTitle: "登録",
leftButtonAction: nil,
rightButtonAction: {
if item.contains(text) {
alertD()
} else {
registDataName(name: text)
item = getDataName()
}
}
)
.frame(width: 0, height: 0, alignment: .center)
早いとこアプデで追加されるといいなぁー

