iosswiftswiftuiviewshowcaseview

Is it possible to reduce the size of showcase in SwiftUI?


I want to present showcase first time after login. so i just found only one showcase framework in iOS called material-showcase-ios but with this i can getting very big view because of that one showcase presents on top of another... so i need to reduce the size of showcase, please help me.

i need to use multiple showcases so here is the code: added this package: github "aromajoin/material-showcase-ios" ~> 0.8.0 and below code

import SwiftUI
import MaterialShowcase

struct ShowcaseHost: UIViewRepresentable {
@Binding var isPresented: Bool
var showcaseItem: ShowcaseItem

func makeUIView(context: Context) -> UIView {
    let view = UIView(frame: .zero)
    DispatchQueue.main.async {
        if isPresented {
            showShowcase(on: view, showcaseItem: showcaseItem)
        }
    }
    return view
}

func updateUIView(_ uiView: UIView, context: Context) {}

func showShowcase(on targetView: UIView, showcaseItem: ShowcaseItem) {
    guard let windowScene = UIApplication.shared.connectedScenes.first as? UIWindowScene,
          let window = windowScene.windows.first else { return }

    // Adjust target view position based on alignment
    targetView.translatesAutoresizingMaskIntoConstraints = false
    window.addSubview(targetView)
    
    // Adjust the size of the target view for better animations
    let targetSize: CGFloat = 50
    
    switch showcaseItem.animation {
    case .topLeading:
        NSLayoutConstraint.activate([
            targetView.topAnchor.constraint(equalTo: window.topAnchor, constant: 50),
            targetView.leadingAnchor.constraint(equalTo: window.leadingAnchor, constant: 50),
            targetView.widthAnchor.constraint(equalToConstant: targetSize),
            targetView.heightAnchor.constraint(equalToConstant: targetSize)
        ])
   
    case .center:
        NSLayoutConstraint.activate([
            targetView.centerXAnchor.constraint(equalTo: window.centerXAnchor),
            targetView.centerYAnchor.constraint(equalTo: window.centerYAnchor),
            targetView.widthAnchor.constraint(equalToConstant: targetSize),
            targetView.heightAnchor.constraint(equalToConstant: targetSize)
        ])
    }

    let imageView = UIImageView(image: UIImage(systemName: "camera.fill"))
    imageView.contentMode = .scaleAspectFit
    imageView.translatesAutoresizingMaskIntoConstraints = false
    targetView.addSubview(imageView)

    NSLayoutConstraint.activate([
        imageView.centerXAnchor.constraint(equalTo: targetView.centerXAnchor),
        imageView.centerYAnchor.constraint(equalTo: targetView.centerYAnchor),
        imageView.widthAnchor.constraint(equalTo: targetView.widthAnchor, multiplier: 0.8),
        imageView.heightAnchor.constraint(equalTo: targetView.heightAnchor, multiplier: 0.8)
    ])
    
    // Configure and show the showcase
    let showcase = MaterialShowcase()
    showcase.setTargetView(view: targetView)
    showcase.primaryText = showcaseItem.primaryText
    showcase.secondaryText = showcaseItem.secondaryText
    showcase.backgroundPromptColor = showcaseItem.backgroundColor
    showcase.primaryTextColor = showcaseItem.textColor
    showcase.secondaryTextColor = showcaseItem.textColor
    showcase.targetHolderColor = UIColor.white

    DispatchQueue.main.asyncAfter(deadline: .now() + 0.1) {
        showcase.show(completion: {
            isPresented = false
            targetView.removeFromSuperview()
        })
    }
}
}

struct ShowcaseItem {
let primaryText: String
let secondaryText: String
let animation: AnimationTypeShowcase
let backgroundColor: UIColor
let textColor: UIColor
}

enum AnimationTypeShowcase {
case topLeading, bottomTrailing, bottomLeading, topTrailing, center
}

and using ShowcaseHost in home screen like this

struct HomeNew: View {

@State private var showShowcase = false
@State private var showShowcaseDashboard = false


var profileShowcase: ShowcaseItem {
    ShowcaseItem(
        primaryText: "Profile",
        secondaryText: "Click here to check out your profile and Transport Details",
        animation: .topLeading,
        backgroundColor: UIColor(red: 0.984, green: 0.906, blue: 0.631, alpha: 1.0), //.systemPink,
        textColor: .white
    )
}

var dashboardShowcase: ShowcaseItem {
    ShowcaseItem(
        primaryText: "Dashboard",
        secondaryText: "Click here to access Dashboards",
        animation: .center,
        backgroundColor: UIColor(red: 0.47, green: 0.75, blue: 0.78, alpha: 1.0),
        textColor: .white
    )
}

var body: some View {
    ZStack{
        Color.Neumorphic.main
            .ignoresSafeArea()
        
        VStack{
            
            VStack{
                HStack(alignment: .center) {
                    URLImageView(url: userPhoto.percentageEncoding(), placeholder: "NoProfilePic", width: 80, height: 80)
                        .cornerRadius(15)
                        .scaledToFit()
                        .overlay(
                            RoundedRectangle(cornerRadius: 15)
                                .stroke(Color.appGreen, lineWidth: 2)
                        )
                    
                        .onTapGesture {
                            if showShowcase {
                                showShowcase = false
                            } else {
                                gotoProfile = true
                            }
                        }
                }
                Spacer()
                
            }
            .padding(16)
        }
        
        ScrollView {
            VStack(spacing: 0) {
                VStack(spacing: 0) {
                    HStack(spacing: 10) {
                        ZStack {
                            
                            HStack {
                                Spacer()
                                Text("View dashboard")
                                    .font(.calibriRegular(with: 16))
                                    .foregroundColor(.appGreen)
                                
                            }
                        }
                    }
                }
                .frame(height: 40)
                
                .onTapGesture {
                    if showShowcaseDashboard {
                        showShowcaseDashboard = false
                    } else {
                        gotoDashboard = true
                    }
                }
            }
        }
        
        if showShowcase {
            ShowcaseHost(isPresented: $showShowcase, showcaseItem: profileShowcase)
                .onAppear {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                        showShowcase = false
                    }
                }
        }
        
        if showShowcaseDashboard {
            ShowcaseHost(isPresented: $showShowcaseDashboard, showcaseItem: dashboardShowcase)
                .onAppear {
                    DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
                        showShowcaseDashboard = false
                    }
                }
        }
    }
}
}

o/p: here how to reduce the size, please help.

enter image description here

enter image description here


Solution

  • I haven't used this framework myself, but I know that the size is basically controlled by the cornerRadius value. According to their documentation, you can control the size of the background by defining your own style, which looks like you're already doing. So just add a line and provide a value for showcase.backgroundRadius:

    // Configure and show the showcase
        let showcase = MaterialShowcase()
        showcase.setTargetView(view: targetView)
        showcase.primaryText = showcaseItem.primaryText
        showcase.secondaryText = showcaseItem.secondaryText
        showcase.backgroundPromptColor = showcaseItem.backgroundColor
        showcase.primaryTextColor = showcaseItem.textColor
        showcase.secondaryTextColor = showcaseItem.textColor
        showcase.targetHolderColor = UIColor.white
        showcase.backgroundRadius = 200 // <-- Here, adjust this value as needed (default is 300)