• iPadおよびiPhoneアプリの共有スペース向けの機能強化

    Shared SpaceのためにiPadとiPhoneアプリを充実させましょう!visionOSでの体験を向上させる方法をお見せし、Designed for iPadアプリにおけるインタラクション、視覚処置とメディアを探求します。

    関連する章

    リソース

    関連ビデオ

    WWDC23

    WWDC20

  • ダウンロード
    Array
    • 3:02 - Tappable VStack with hover effect

      struct TappableCard: View {
         // Sample card
         var imageName = "BearsInWater"
         var headline = "Bear Fishing"
         var timeAgo = "42 Minutes ago"
         
         var body: some View {
            VStack {
               VStack(alignment: .leading) {
                  Image(imageName)
                     .resizable()
                     .clipped()
                     .aspectRatio(contentMode: .fill)
                     .frame(width: 300, height: 250, alignment: .center)
                  Text(headline)
                     .padding([.leading])
                     .font(.title2)
                     .foregroundColor(.black)
               }
               Divider()
               HStack {
                  HStack {
                     Text(timeAgo)
                        .frame(alignment: .leading)
                        .foregroundColor(.black)
                  }
                  .padding([.leading])
                  Spacer()
                  VStack(alignment: .trailing) {
                     Button { print("Present menu options") } label: {
                        Image(systemName: "ellipsis")
                           .foregroundColor(.black)
                     }
                  }
               }
               .padding(EdgeInsets(top: 5, leading: 5, bottom: 5, trailing: 5))
            }
            .frame(width: 300, height: 350, alignment: .top)
            .hoverEffect()
            .background(.white)
            .overlay(
               RoundedRectangle(cornerRadius: 10)
                  .stroke(Color(.sRGB, red: 150/255, green: 150/255, blue: 150/255, opacity: 0.1), lineWidth: 3.0)
            )
            .cornerRadius(10)
            .onTapGesture {
               print("Present card detail")
            }
         }
      }
    • 4:08 - Custom player with tap targets that are larger than the hover effect bounds

      struct ContentView: View {
         var body: some View {
            VStack {
               // Video player
               HStack {
                  Button { print("Going back 10 seconds") } label: {
                     Image(systemName: "gobackward.10")
                        .padding(.trailing)
                        .contentShape(.hoverEffect, CustomizedRectShape(customRect: CGRect(x: -75, y: -40, width: 100, height: 100)))
                        .foregroundStyle(.white)
                        .frame(width: 500, height: 834, alignment: .trailing)
                  }
                  Button { print("Play") } label: {
                     Image(systemName: "play.fill")
                        .font(.title)
                        .foregroundStyle(.white)
                        .frame(width: 100, height: 100, alignment: .center)
                  }
                  .padding()
                  Button { print("Going into the future 10 seconds") } label: {
                     Image(systemName: "goforward.10")
                        .padding(.leading)
                        .contentShape(.hoverEffect, CustomizedRectShape(customRect: CGRect(x: 0, y: -40, width: 100, height: 100)))
                        .foregroundStyle(.white)
                        .frame(width: 500, height: 834, alignment: .leading)
                  }
               }
               .frame(
                    minWidth: 0,
                    maxWidth: .infinity,
                    minHeight: 0,
                    maxHeight: .infinity,
                    alignment: .center
               )
            }
            .frame(
                 minWidth: 0,
                 maxWidth: .infinity,
                 minHeight: 0,
                 maxHeight: .infinity,
                 alignment: .topLeading
            )
            .background(.black)
         }
      }
      
      struct CustomizedRectShape: Shape {
         var customRect: CGRect
         
         func path(in rect: CGRect) -> Path {
            var path = Path()
            
            path.move(to: CGPoint(x: customRect.minX, y: customRect.minY))
            path.addLine(to: CGPoint(x: customRect.maxX, y: customRect.minY))
            path.addLine(to: CGPoint(x: customRect.maxX, y: customRect.maxY))
            path.addLine(to: CGPoint(x: customRect.minX, y: customRect.maxY))
            path.addLine(to: CGPoint(x: customRect.minX, y: customRect.minY))
            
            return path
         }
      }
    • 5:14 - Button with custom buttonStyle, then adding a hover effect to the button

      struct ContentView: View {
          var body: some View {
              VStack {
               Button("Howdy y'all") { print("🤠") }
                  .buttonStyle(SixColorButton())
              }
              .padding()
          }
      }
      
      struct SixColorButton: ButtonStyle {
         func makeBody(configuration: Configuration) -> some View {
            configuration.label
               .padding()
               .font(.title)
               .foregroundStyle(.white)
               .bold()
               .background {
                  // Background color bands
                  ZStack {
                     Color.black
                     HStack(spacing: 0) {
                        // GREEN
                        Rectangle()
                           .foregroundStyle(Color(red: 125/255, green: 186/255, blue: 66/255))
                           .frame(width: 16)
                        // YELLOW
                        Rectangle()
                           .foregroundStyle(Color(red: 240/255, green: 187/255, blue: 64/255))
                           .frame(width: 16)
                        // ORANGE
                        Rectangle()
                           .foregroundStyle(Color(red: 225/255, green: 137/255, blue: 50/255))
                           .frame(width: 16)
                        // RED
                        Rectangle()
                           .foregroundStyle(Color(red: 200/255, green: 73/255, blue: 65/255))
                           .frame(width: 16)
                        // PURPLE
                        Rectangle()
                           .foregroundStyle(Color(red: 134/255, green: 64/255, blue: 151/255))
                           .frame(width: 16)
                        // BLUE
                        Rectangle()
                           .foregroundStyle(Color(red: 75/255, green: 154/255, blue: 218/255))
                           .frame(width: 16, height: 500)
                     }
                     .opacity(0.7)
                     .rotationEffect(.degrees(35))
                  }
               }
               .cornerRadius(10)
               .hoverEffect()
         }
      }
    • 5:46 - Honey comb app with custom shape buttons, then adding hover effects that clip to bounds of the honey comb shape

      struct ContentView: View {
          var body: some View {
            VStack {
               Button { print("🐝") } label: {
                  // Button label
                  HoneyComb()
                     .fill(.yellow)
                     .frame(width: 300, height: 300)
                     .contentShape(.hoverEffect, HoneyComb())
                  }
               }
               .frame(width: 400, height: 400, alignment: .center)
               .background(.black)
               .padding()
            }
          }
      }
      
      struct HoneyComb: Shape {
         func path(in rect: CGRect) -> Path {
            var path = Path()
            path.move(to: CGPoint(x: rect.minX + (rect.width * 0.25), y: rect.minY))
            path.addLine(to: CGPoint(x: rect.maxX - (rect.maxX * 0.25), y: rect.minY))
            path.addLine(to: CGPoint(x: rect.maxX, y: rect.midY))
            path.addLine(to: CGPoint(x: rect.maxX - (rect.maxX * 0.25), y: rect.maxY))
            path.addLine(to: CGPoint(x: rect.minX + (rect.width * 0.25), y: rect.maxY))
            path.addLine(to: CGPoint(x: rect.minX, y: rect.midY))
            path.addLine(to: CGPoint(x: rect.minX + (rect.width * 0.25), y: rect.minY))
            return path
         }
      }