我在 SwiftUI 中有串列專案,當我用星形圖示設定最喜歡的專案時,我想將專案移動到頂部,并且我想再次為第二個專案重復它,這可能嗎?我知道有移動行的例子,但我不明白我會怎么做。
模型:
struct Restaurant: Identifiable {
var id = UUID()
var name: String
var image: String
var isFavorite: Bool = false
}
基本影像行:
struct BasicImageRow: View {
var restaurant: Restaurant
var body: some View {
HStack {
Image(restaurant.image)
.resizable()
.frame(width: 40, height: 40)
.cornerRadius(5)
Text(restaurant.name)
if restaurant.isFavorite {
Spacer()
Image(systemName: "star.fill")
.foregroundColor(.yellow)
}
}
}
}
看法:
import SwiftUI
struct ContentView: View {
@State private var selectedRestaurant: Restaurant?
@State private var restaurants = [ Restaurant(name: "Cafe Deadend", image: "cafedeadend"),
Restaurant(name: "Homei", image: "homei"),
Restaurant(name: "Teakha", image: "teakha"),
Restaurant(name: "Cafe Loisl", image: "cafeloisl"),
Restaurant(name: "Petite Oyster", image: "petiteoyster"),
Restaurant(name: "For Kee Restaurant", image: "forkeerestaurant"),
]
var body: some View {
List {
ForEach(restaurants) { restaurant in
BasicImageRow(restaurant: restaurant)
.contextMenu {
Button(action: {
// mark the selected restaurant as check-in
self.checkIn(item: restaurant)
}) {
HStack {
Text("Check-in")
Image(systemName: "checkmark.seal.fill")
}
}
Button(action: {
// delete the selected restaurant
self.delete(item: restaurant)
}) {
HStack {
Text("Delete")
Image(systemName: "trash")
}
}
Button(action: {
// mark the selected restaurant as favorite
self.setFavorite(item: restaurant)
}) {
HStack {
Text("Favorite")
Image(systemName: "star")
}
}
}
.onTapGesture {
self.selectedRestaurant = restaurant
}
.actionSheet(item: self.$selectedRestaurant) { restaurant in
ActionSheet(title: Text("What do you want to do"), message: nil, buttons: [
.default(Text("Mark as Favorite"), action: {
self.setFavorite(item: restaurant)
}),
.destructive(Text("Delete"), action: {
self.delete(item: restaurant)
}),
.cancel()
])
}
}
}
}
private func setFavorite(item restaurant: Restaurant) {
if let index = self.restaurants.firstIndex(where: { $0.id == restaurant.id }) {
self.restaurants[index].isFavorite.toggle()
}
}
}
uj5u.com熱心網友回復:
一種方法是使用一個FavoriteModel可以跟蹤專案何時被標記的方法。
struct FavoriteModel{
var isFavorite: Bool = false
var timeStamp: Date = Date()
mutating func toogleFavorite(){
isFavorite.toggle()
timeStamp = Date()
}
}
然后按專案排序timestamp
ForEach(restaurants.sorted(by: {
$0.isFavorite.timeStamp > $1.isFavorite.timeStamp
})) { restaurant in
在某些用例中,跟蹤選擇該專案為收藏的人甚至可能是有益的
struct FavoriteModel{
var isFavorite: Bool = false
var timeStamp: Date = Date()
var userIds: Set<UUID> = []
mutating func toogleFavorite(userId: UUID){
isFavorite.toggle()
timeStamp = Date()
if isFavorite{
userIds.insert(userId)
}else{
userIds.remove(userId)
}
}
}
下面是一套完整的作業代碼。
struct Restaurant: Identifiable {
var id = UUID()
var name: String
var image: String
var isFavorite: FavoriteModel = .init()
}
struct BasicImageRow: View {
var restaurant: Restaurant
var body: some View {
HStack {
Image(restaurant.image)
.resizable()
.frame(width: 40, height: 40)
.cornerRadius(5)
Text(restaurant.name)
if restaurant.isFavorite.isFavorite {
Spacer()
Image(systemName: "star.fill")
.foregroundColor(.yellow)
}
}
}
}
struct RestaurantView: View {
@State private var selectedRestaurant: Restaurant?
@State private var restaurants = [ Restaurant(name: "Cafe Deadend", image: "cafedeadend"),
Restaurant(name: "Homei", image: "homei"),
Restaurant(name: "Teakha", image: "teakha"),
Restaurant(name: "Cafe Loisl", image: "cafeloisl"),
Restaurant(name: "Petite Oyster", image: "petiteoyster"),
Restaurant(name: "For Kee Restaurant", image: "forkeerestaurant"),
]
var body: some View {
List {
ForEach(restaurants.sorted(by: {
$0.isFavorite.timeStamp > $1.isFavorite.timeStamp
})) { restaurant in
BasicImageRow(restaurant: restaurant)
.contextMenu {
Button(action: {
// mark the selected restaurant as check-in
//self.checkIn(item: restaurant)
}) {
HStack {
Text("Check-in")
Image(systemName: "checkmark.seal.fill")
}
}
Button(action: {
// delete the selected restaurant
//self.delete(item: restaurant)
}) {
HStack {
Text("Delete")
Image(systemName: "trash")
}
}
Button(action: {
// mark the selected restaurant as favorite
self.setFavorite(item: restaurant)
}) {
HStack {
Text("Favorite")
Image(systemName: "star")
}
}
}
.onTapGesture {
self.selectedRestaurant = restaurant
}
.actionSheet(item: self.$selectedRestaurant) { restaurant in
ActionSheet(title: Text("What do you want to do"), message: nil, buttons: [
.default(Text("Mark as Favorite"), action: {
self.setFavorite(item: restaurant)
}),
.destructive(Text("Delete"), action: {
//self.delete(item: restaurant)
}),
.cancel()
])
}
}
}
}
private func setFavorite(item restaurant: Restaurant) {
if let index = self.restaurants.firstIndex(where: { $0.id == restaurant.id }) {
self.restaurants[index].isFavorite.toogleFavorite()
}
}
}
struct RestaurantView_Previews: PreviewProvider {
static var previews: some View {
RestaurantView()
}
}
uj5u.com熱心網友回復:
您只需要更新withAnimation塊內的餐廳,SwiftUI 就會知道如何使用他們的 id 為他們設定影片
ForEach(restaurants) { restaurant in
Button(action: {
withAnimation {
var favoritedRestaurant = restaurant
favoritedRestaurant.isFavorite = true
restaurants = [favoritedRestaurant] restaurants.filter { $0.id != restaurant.id }
}
}) {
BasicImageRow(restaurant: restaurant)
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/438918.html
