iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0
Mobile Development

使用 SwiftUI 讓有趣的點子變成 Apps系列 第 15

D15 - 使用 SwiftUI 讓有趣的點子變成 Apps{葛麗絲逆走鐘: 彈出一個 sheet 裝載剛剛的 WKWebView}

  • 分享至 

  • xImage
  •  

剛剛做好了 WebView,然後我們需要一個 button,在點擊之後把一個新的 View 從下方滑到上方。這個過場在 iPhone 裡面是非常常見的操作,先做一個 Button 在 ClockContainerView 上方。

var body: some View {
    ZStack {
      
      VStack {
        
        Button {
          // TODO: - 發動彈窗
        } label: {
          Image(systemName: "person.crop.circle")
            .font(.system(size: 50))
            .foregroundColor(.brown)
        }
        Spacer()
      }
      
      Group {
        ClockDialView()
        HandShape(handLength: .hour)
          .fill(Color.blue)
          .rotationEffect(Angle(degrees: clockwork.hourAngle))
        HandShape(handLength: .minute)
          .fill(Color.cyan)
          .rotationEffect(Angle(degrees: clockwork.minuteAngle))
        HandShape(handLength: .second)
          .fill(Color.red)
          .rotationEffect(Angle(degrees: clockwork.secondAngle))
        Circle()
          .fill(Color.orange)
          .frame(width: 20, height: 20, alignment: .center)
      }
      .frame(width: width, height: height, alignment: .center)
    }
  }

這個 Profile Button,按下去後會將 Grace Hopper 的 wiki 頁面,從下方彈出來。

https://ithelp.ithome.com.tw/upload/images/20220915/201406229harxqDiDd.png

SwiftUI 實現 present

如 D3(補上連結) 所說,SwiftUI 的框架,要讓 View 改變,就要讓 State 改變,接下來框架就會幫你做完剩下的事情。在 SwiftUI 裡面,類似 UIKit 的 present 的形為,呼叫為 sheet,isPresented 是綁定一個布林值,如果為 true,就呈現,反之,就縮下去。onDismiss 可以不寫動作,最後的 content,就是你要呈現的 view。

SwiftUI 對 Sheet 的說明文件。

https://developer.apple.com/documentation/SwiftUI/View/sheet(isPresented:onDismiss:content:)

程式碼

在 View 裡面,先宣告這個需不需要 present 的 State 變數。


@State private var isShowingGraceWikiSheet = false
/// Grace Hopper Wiki 網址
private let graceWikiPageURL = "https://en.wikipedia.org/wiki/Grace_Hopper"

然後更改上方程式碼中的 Button,Button 需要發動 toggle(),讓 isShowingGraceWikiSheet 切換,並把 sheet modifier 加上。

Button {
          
          isShowingGraceWikiSheet.toggle()
        } label: {
          Image(systemName: "person.crop.circle")
            .font(.system(size: 50))
            .foregroundColor(.brown)
        }
        .sheet(isPresented: $isShowingGraceWikiSheet) {
          BCWebView(urlString: graceWikiPageURL)
        }

這樣,在點擊 Button 後,就能彈出 Grace Hopper 的 wiki 頁面了。

https://ithelp.ithome.com.tw/upload/images/20220915/201406224s16MF1Msh.png

這個 present 的效果,是有自帶由上往下滑動後,把前面的 view dismiss 掉。不過如果你彈出來的是個可以上下滑動的頁面,那在模擬器上滑起來,就會變得不容易觸發 dismiss。

解法是有的,就是在彈出來的這個頁面,加上一個可以觸發自己 dismiss 的 button,讓外面滑不動的時候,彈起來的頁面還可以 dismiss。稍微修改一下 BCWebView。

struct BCWebView: View {
  
  @Environment(\.dismiss) var dismiss
  
  let urlString: String
  
  var body: some View {
    
    if let url = URL(string: urlString) {
      VStack {
        HStack {
          Spacer()
          Button {
            dismiss() // 讓這一頁發動 dismiss
          } label: {
            Image(systemName: "x.circle")
              .font(.system(size: 44))
              .tint(.black)
              .padding([.top, .trailing])
          }
        }
        WKWebViewContainer(url: url)
      }
    } else {
      URLNotCorrectView()
    }
  }
}

現在,試著點擊一下彈起來的 wiki 頁面右上方 X,如果手勢沒辦法發動,就可以用這個 X 來發動 dismiss。


上一篇
D14 - 使用 SwiftUI 讓有趣的點子變成 Apps{葛麗絲逆走鐘: 加上 WebView 讀取外部網頁}
下一篇
D16 - 葛麗絲逆走鐘: 顏色選擇器 ColorPicker
系列文
使用 SwiftUI 讓有趣的點子變成 Apps30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言