8 SwiftUI tips that make colleagues next door light up and say it's too curly

In the daily SwiftUIdevelopment process, there are often some " small bugs " that catch us off guard and make our heads feel cold. These problems may be caused by our own unfamiliar SwiftUIgrammar, and some SwiftUIinherent defects, after all, it is a new language.

So this chapter introduces some SwiftUIdevelopment tips to help us avoid those pits that make us bald .

1. How to remove the dividing line LineSeparator in the List view?

SwiftUIAn evolutionary version of arguably yes, in which Listwe use the modifier to change the style of the split line to none. Example:UIKit中TableViewUIKitseparatorColor

tableView.separatorColor = .clear

The SwiftUImethod used in is similar, SwiftUIthe Listbottom layer of in is used UITableView, we can call AppearanceAPIto remove the split line style. Example:

UITableView.appearance().separatorColor = .clear

1.png

However, using this method will cause Appall of the Listpages, including other pages, to Listautomatically remove the dividing line, because it UITableViewis Listthe bottom layer, our modifier is on UITableView.

In the future, if we want to restore the dividing line on other pages, such as the settings page, we need to assign the style of the dividing line. Example:

UITableView.appearance().separatorColor = .systemGray4

2.png

2. How to hide arrows in List view?

In UIKit, we use a accessoryTypemodifier to disable disclosurethe indicator, which is the arrow on the right. Example:

cell.accessoryType = .none

In SwiftUI, unfortunately, there is Appleno dedicated APIsetting to hide the disclosureindicator, which would be a bit of a hassle.

我们建立一个List列表来看看,当我们使用NavigationLink跳转到DetailView详情页时,系统就会自动展示右侧的箭头,示例:

3.png

那么我们试试自己来实现隐藏disclosure指示器。

struct ContentView: View {
    var body: some View {

        NavigationView {
            List {
                ForEach(1 ... 4, id: \.self) { index in
                    ZStack(alignment: .leading) {
                        NavigationLink(
                            destination: DetailView()) {
                        }
                        .opacity(0)

                        Text("第 \(index)页")
                    }
                }
            }.navigationTitle("列表")
        }
    }
}

4.png

上述代码中,我们使用ZStack层叠视图将整个NavigationLink的视图包裹起来,然后使用opacity修饰符把disclosure指示器隐藏。

看起来不错!

3、如何修改整个视图的背景颜色?

List列表中,由于我们使用SwiftUI自带的列表组件,它会默认给整个视图填充一个背景颜色以凸显列表,这时我们追求页面整体性时,需要给List视图加一个背景颜色。

UIKit中,我们可以直接给视图加背景颜色,示例:

view.backgroundColor = UIColor.colorF6F7FB()

首先,我们要去掉原有的List列表颜色,示例:

init() {

    UITableView.appearance().backgroundColor = .clear

}

然后在业务代码中,我们可以使用ZStack层叠视图和Color的方式设置List的背景颜色,示例:

Color(red: 132.0 / 255.0, green: 161.0 / 255.0, blue: 255.0 / 255.0).edgesIgnoringSafeArea(.all)

5.png

不错不错!

4、如何通过网络请求显示一张网络图片?

在常用的设置页面或者我的页面,会使用到用户头像等作为用户登录示例,除了使用第三方网络请求框架外,我们也可以使用SwiftUI自带的网络图片组件,示例:

AsyncImage(url: URL(string: imageURL))
    .aspectRatio(contentMode: .fit)
    .frame(minWidth: 120, maxWidth: 120, minHeight: 120, maxHeight: 120)
    .cornerRadius(8)

6.png

上述代码中,我们只需要定义一个图片的网络地址,就可以使用AsyncImage组件呈现一张图片出来,并且AsyncImageImage一样,可以使用修饰符修改大小的参数。

5、如何绘制带有边角的图形?

SwiftUI开发过程中,我们常常会看到一些带有部分圆角的形状,这又是如何实现的呢?

7.png

我们可以通过图片的方式展示,也可以自己根据形状绘制,下面我们尝试使用Shape形状来实现这个效果。示例:

struct CShape: Shape {
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(
            roundedRect: rect,
            byRoundingCorners: [.topRight, .bottomLeft],
            cornerRadii: CGSize(width: 55, height: 55)
        )
        return Path(path.cgPath)
    }
}

上述代码中,我们绘制了一个形状CShape结构体,在结构体中我们的定义了一个方法path,它返回一个Path路径。

我们使用贝塞尔曲线UIBezierPath进行绘制,在右上topRight和左下bottomLeft绘制曲率。

接下来我们在视图中使用,示例:

struct CShapeView: View {
    var body: some View {
       Rectangle()
            .fill(LinearGradient(gradient: Gradient(colors: [Color.blue, Color.green]), startPoint: .leading, endPoint: .trailing))
            .frame(width: 100, height: 100)
            .clipShape(CShape())
    }
}

8.png

上述代码中,我们绘制了一个矩形Rectangle,给它填充了一个蓝色过渡到绿色的渐变色,然后设置了大小为100*100

最后我们使用clipShape修饰符切割曲线,切割方式为上面设置好的CShape

这样,我们就完成了一个类似叶子效果的带边角的形状。

6、如何绘制虚线边框?

在新版的Xcode中,我们已经不能直接使用border修饰符给按钮加边框了,那我们该如何给按钮加边框线呢?

其实很简单,我们可以使用overlay修饰符在按钮上覆盖一层边框,示例:

Text("文如秋雨")
    .font(.title)
    .foregroundColor(.blue)
    .padding()
    .overlay(
        RoundedRectangle(cornerRadius: 30)
            .stroke(Color(.systemGray5), lineWidth: 2)
    )

9.png

上述代码中,我们使用overlay覆盖了一层圆角矩形RoundedRectangle,圆角度数为30,并且使用stroke修饰符给圆角赋予了一个灰色systemGray5,和2的线宽。

这是边框的实现方式,那么虚线边框我们使用的是Capsule容器。示例:

Text("文如秋雨")
    .font(.title)
    .foregroundColor(.blue)
    .padding()
    .overlay(
        Capsule(style: .continuous)
            .stroke(Color.blue, style: StrokeStyle(lineWidth: 2, dash: [10]))
    )

10.png

上述代码中,我们覆盖的是Capsule容器,然后将Capsule容器的样式指定为StrokeStyleStrokeStyle样式中线宽为2,线段间距为10

如此,我们便实现了绘制一个虚线边框

7、如何分享文本和图片?

在实际的开发应用中,我们常常会在App中使用分享操作,将某一段文字或者图片分享出去,这是如何实现的呢?

首先我们先实现分享的方法,示例:

struct ShareSheet: UIViewControllerRepresentable {
    var items: [Any]
    func makeUIViewController(context: Context) -> UIActivityViewController {
        let controller = UIActivityViewController(activityItems: items, applicationActivities: nil)
        return controller
    }
    func updateUIViewController(_ uiViewController: UIActivityViewController, context: Context) {
    }
}

上述代码中,我们创建了一个ShareSheet结构体,它遵循UIViewControllerRepresentable协议。

我们声明了一个items变量是随机类型,便于后续我们存储不同类型的内容。然后定义了一个方法makeUIViewController,调用系统的UIActivityViewController视图方法,分享声明好的items内容。

接下来,我们来完成视图部分,示例:

struct ShareLinkView: View {
    let items = ["https://juejin.cn/user/3897092103223517"]
    @State var showingSheet: Bool = false

    var body: some View {
        HStack {
            Image(systemName: "square.and.arrow.up")
            Text("分享")
        }
        .onTapGesture {
            showingSheet.toggle()
        }
        .sheet(isPresented: $showingSheet) {
            ShareSheet(items: items)
        }
    }
}

11.png

上述代码中,我们声明了一个常量,存储我们的网站地址,然后使用ImageText创建了一个分享的样式,调用sheet弹窗方法打开弹窗,弹窗的内容为我们声明好的ShareSheet视图,然后将声明好的内容传入进行分享。效果如下:

12.png

8、如何在按钮点击时有震动反馈?

iOS很突出的一点是它的线性马达所带来的反馈体验,让我们在点击屏幕某些操作时能够接收到App提供的反馈信息。

如果我们需要给App的某些操作加入一些震动反馈,该如何实现?

我们可以使用UINotificationFeedbackGenerator来实现震动反馈的效果,示例:

struct Haptics {
    static func hapticSuccess() {
        let generator = UINotificationFeedbackGenerator()
        generator.notificationOccurred(.success)
    }

    static func hapticWarning() {
        let generator = UINotificationFeedbackGenerator()
        generator.notificationOccurred(.warning)
    }
}

In the above code, we created a structure Hapticsand Hapticsdefined 2a vibration feedback effect in it, one for successful feedback and one for failure feedback.

Then we use it in the actual business view, example:

struct HapticsView: View {
    var body: some View {

        VStack(spacing:40) {
            Text("成功时的反馈")
                .padding()
                .foregroundColor(.white)
                .background(Color.green)
                .cornerRadius(5)
                .onTapGesture {
                    Haptics.hapticSuccess()
                }

            Text("失败时的反馈")
                .padding()
                .foregroundColor(.white)
                .background(Color.gray)
                .cornerRadius(5)
                .onTapGesture {
                    Haptics.hapticWarning()
                }
        }
    }
}

13.png

In the above code, we have created 2a button with different styles. When we 点击按钮do, we will call the vibration feedback method to achieve the effect of letting the user click.

Vibration feedback is often used in long-press or some warning business scenarios, and can be used depending on the situation.

summary

Okay! That's all there is to this chapter, isn't it a bit bright ?

If you have any other SwiftUItips, please share them.

If this column is helpful to you, please like, comment, and follow~

I am participating in the recruitment of the creator signing program of the Nuggets Technology Community, click the link to register and submit .

Guess you like

Origin juejin.im/post/7121516359095156750