I would like to add vertical scrolling to my custom layout. I don't know how to do it. I have added my code below for reference. Thanks in Advance.
struct TokenData {
let email: String
}
let gradientColor = LinearGradient(colors: [Color(red: 0/255, green: 204/255, blue: 172/255), Color(red: 1/255, green: 99/255, blue: 240/255)], startPoint: .top, endPoint: .bottom)
struct TokenView: View {
@Binding var dataSource: [TokenData]
@Binding var tokenData: TokenData
var body: some View {
HStack {
Text(tokenData.email)
.foregroundStyle(.white)
Button(action: {
if let index = self.dataSource.firstIndex(where: { $0.email == tokenData.email }) {
self.dataSource.remove(at: index)
} else {
assertionFailure("Should not come here.. ")
}
}, label: {
Image(systemName: "multiply")
.renderingMode(.template)
})
.buttonStyle(.plain)
.foregroundStyle(.white)
}
.padding(3)
.background(gradientColor)
.clipShape(RoundedRectangle(cornerRadius: 4))
}
}
struct TokenFieldView: View {
@State var resultData: [TokenData] = []
@State var inputData: String = ""
@State var layout: AnyLayout = AnyLayout(CustomTokenFieldLayout())
var body: some View {
VStack(alignment: .center) {
HStack(alignment: .center) {
TextField("Enter mail Ids..", text: $inputData)
.onSubmit {
resultData.append(TokenData(email: inputData))
}
Button {
self.resultData.removeAll()
} label: {
Text("clear")
}
}
Divider()
ScrollView(.vertical) {
layout {
ForEach(resultData.indices, id: \.self) { index in
TokenView(dataSource: $resultData, tokenData: self.$resultData[index])
}
}
}
}
.onAppear(perform: {
let window = NSApplication.shared.windows.first
window?.level = .floating
})
}
}
struct CustomTokenFieldLayout: Layout {
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
return CGSize(width: proposal.width!, height: proposal.height!)
}
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
guard !subviews.isEmpty else {
return
}
var point = bounds.origin
let hSpacing: Double = 5
let vSpacing: Double = 5
point.x += hSpacing
point.y += vSpacing
for subview in subviews {
if (point.x + subview.dimensions(in: .unspecified).width + hSpacing) > bounds.width {
point.y += (subview.dimensions(in: .unspecified).height + vSpacing)
point.x = hSpacing
}
subview.place(at: point, anchor: .leading, proposal: proposal)
point.x += (subview.dimensions(in: .unspecified).width + hSpacing)
}
}
}
When I try to add my custom layout inside scrollview, I get zero proposalview.width and height in Layout definition. Could anyone please explain why that is happening?
struct TokenFieldView: View {
@State var resultData: [TokenData] = []
@State var inputData: String = ""
@State var layout: AnyLayout = AnyLayout(CustomTokenFieldLayout())
var body: some View {
VStack(alignment: .center) {
HStack(alignment: .center) {
TextField("Enter mail Ids..", text: $inputData)
.onSubmit {
resultData.append(TokenData(email: inputData))
}
Button {
self.resultData.removeAll()
} label: {
Text("clear")
}
}
Divider()
ScrollView {
layout {
ForEach(resultData.indices, id: \.self) { index in
TokenView(dataSource: $resultData, tokenData: self.$resultData[index])
}
}
}
}
.onAppear(perform: {
let window = NSApplication.shared.windows.first
window?.level = .floating
})
}
}

