1

我为日期选择器自定义编写了以下代码,并将输出作为输出图像

在这里,我想以这种方式为日期选择器添加前进和后退按钮期望输出

任何人都可以帮助我修改代码以添加带有期望输出的前进和后退按钮] 2

给我任何想法或与我分享任何参考。

    struct CalendarDay: Identifiable {
    let id = UUID()
    var number: String
    var weekday: String
    var isToday: Bool
}

struct ContentView: View {
    @State var days = [CalendarDay]()
    
    var body: some View {
        ZStack{
            VStack {
                
                Button(action:{
                    //Button Action
                    })
                    .padding(.leading, 10)
                Spacer()
                ScrollView(.horizontal, showsIndicators: false){
                    HStack(spacing: 20) {
                  ForEach(days.indices, id: \.self) { i in
                        CalendarView(
                            number: self.days[i].number,
                            days: self.days[i].weekday,
                            color: self.days[i].isToday ? #colorLiteral(red: 0.9060331583, green: 0.2547450066, blue: 0.3359550834, alpha: 1) : #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
                            textcolor: self.days[i].isToday ? #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) : #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
                        )
                            .onTapGesture{
                                print(self.days[i])
                                // this is just for replacing the current selection
                                for j in self.days.indices { self.days[j].isToday = false }
                                self.days[i].isToday = true
                            }
                    }}
                    .padding(.leading,10)
                    .padding(.bottom, 10)
                    .shadow(radius: 3, x: 3, y: 3)
                }
                Spacer()
                Button(action:{
                                   //Button Action
                                   })
                                   .padding(.leading)
                               Spacer()
                
            }
        }
        .onAppear {
            self.getCurrentWeekdays()
        }
    }
    
    func getCurrentWeekdays() {
        /// from https://stackoverflow.com/a/62355272/14351818
        let dateComponents = Calendar(identifier: .gregorian).dateComponents([.yearForWeekOfYear, .weekOfYear], from: Date())
        let startOfWeek = Calendar(identifier: .gregorian).date(from: dateComponents)!
        let startOfWeekNoon = Calendar(identifier: .gregorian).date(bySettingHour: 12, minute: 0, second: 0, of: startOfWeek)!
        
        days = (0...6).map {
            let calendar = Calendar(identifier: .gregorian)
            let date = calendar.date(byAdding: .day, value: $0, to: startOfWeekNoon)!
            
            let numberDateFormatter = DateFormatter()
            numberDateFormatter.dateFormat = "d"
            let number = numberDateFormatter.string(from: date)
            
            let weekdayDateFormatter = DateFormatter()
            weekdayDateFormatter.dateFormat = "E"
            let weekday = weekdayDateFormatter.string(from: date)
            
            let calendarDay = CalendarDay(
                number: number,
                weekday: weekday,
                isToday: calendar.component(.day, from: Date()) == calendar.component(.day, from: date)
            )
            
            return calendarDay
        }
        
    }
}

struct CalendarView: View {
    var number : String
    var days : String
    var color : UIColor
    var textcolor : UIColor
    
    var body: some View {
        VStack{
            Text(self.number)
                .font(.system(size: 20, weight: .bold, design: .rounded))
                .foregroundColor(Color(self.textcolor))
            Text(self.days)
                .font(.headline)
                .foregroundColor(Color(self.textcolor))
        }.padding([.top,.bottom], 10)
            .padding([.leading,.trailing],10)
            .background(Color(self.color))
            .cornerRadius(30)
    }
}
4

2 回答 2

1

您也可以尝试如下:

您可以将Text视图替换Image为按钮视图。后退和前进按钮保留其位置,而日期选择器仍可滚动。

import SwiftUI

struct CalendarDay: Identifiable {
    let id = UUID()
    var number: String
    var weekday: String
    var isToday: Bool
}

struct Test1: View {
    @State var days = [CalendarDay]()
    
    var body: some View {
        
        HStack(){
            Button {
                
            } label: {
                
                ZStack {
                    
                    Circle()
                        .fill(Color.red)
                        .opacity(0.6)
                    
                    Circle()
                        .strokeBorder(Color.red, lineWidth: 1)
                    
                    Text("B").foregroundColor(.white)
                    
                }.frame(width: 30, height: 30)
            }.padding([.leading],3)
            
            HStack(alignment:.center){
                GeometryReader{ proxy in
                    ScrollView(.horizontal) {
                        
                        LazyHStack {
                            ForEach(days.indices, id: \.self) { i in
                                CalendarView(
                                    number: days[i].number,
                                    days: days[i].weekday,
                                    color: days[i].isToday ? #colorLiteral(red: 0.9060331583, green: 0.2547450066, blue: 0.3359550834, alpha: 1) : #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
                                    textcolor: days[i].isToday ? #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) : #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1), proxy: proxy
                                )
                                .onTapGesture{
                                    print(days[i])
                                    // this is just for replacing the current selection
                                    for j in days.indices { days[j].isToday = false }
                                    days[i].isToday = true
                                }
                            }
                        }
                    }
                }
            }
            .padding([.trailing,.leading],3)
            
            
            Button {
                
            } label: {
                ZStack {
                    Circle()
                        .fill(Color.red)
                        .opacity(0.6)
                    
                    Circle()
                        .strokeBorder(Color.red, lineWidth: 1)
                    
                    Text("F").foregroundColor(.white)
                }.frame(width: 30, height: 30)
            }.padding([.trailing],3)
        }
        
        .shadow(radius: 3, x: 3, y: 3)
        .onAppear {
            getCurrentWeekdays()
        }
    }
    
    func getCurrentWeekdays() {
        /// from https://stackoverflow.com/a/62355272/14351818
        let dateComponents = Calendar(identifier: .gregorian).dateComponents([.yearForWeekOfYear, .weekOfYear], from: Date())
        let startOfWeek = Calendar(identifier: .gregorian).date(from: dateComponents)!
        let startOfWeekNoon = Calendar(identifier: .gregorian).date(bySettingHour: 12, minute: 0, second: 0, of: startOfWeek)!
        
        days = (0...20).map {
            let calendar = Calendar(identifier: .gregorian)
            let date = calendar.date(byAdding: .day, value: $0, to: startOfWeekNoon)!
            
            let numberDateFormatter = DateFormatter()
            numberDateFormatter.dateFormat = "d"
            let number = numberDateFormatter.string(from: date)
            
            let weekdayDateFormatter = DateFormatter()
            weekdayDateFormatter.dateFormat = "E"
            let weekday = weekdayDateFormatter.string(from: date)
            
            let calendarDay = CalendarDay(
                number: number,
                weekday: weekday,
                isToday: calendar.component(.day, from: Date()) == calendar.component(.day, from: date)
            )
            
            return calendarDay
        }
        
    }
}
struct CalendarView: View {
    var number : String
    var days : String
    var color : UIColor
    var textcolor : UIColor
    var proxy: GeometryProxy
    
    var body: some View {
        VStack{
            Text(self.number)
                .font(.system(size: 20, weight: .bold, design: .rounded))
                .foregroundColor(Color(self.textcolor))
            Text(self.days)
                .font(.headline)
                .foregroundColor(Color(self.textcolor))
        }
        
        .frame(width: proxy.size.width * 0.18, height:  proxy.size.width * 0.2)
        .background(Color(self.color))
        .cornerRadius(30)
    }
}

在此处输入图像描述

于 2021-06-09T10:52:17.743 回答
1

你可以尝试这样的事情:为 ScrollViewReader 编辑

struct ContentView: View {

@State var days = [CalendarDay]()
@State var selectedDay: Int = 0

var body: some View {
    ScrollViewReader { scrollProxy in
        HStack {
            Button(action: {
                if selectedDay > 0 {
                    for j in days.indices { days[j].isToday = false }
                    days[selectedDay-1].isToday = true
                    selectedDay -= 1
                    withAnimation { scrollProxy.scrollTo(selectedDay) }
                }
            }) {
                Image(systemName: "chevron.left.circle.fill")
            }
            ZStack{
                VStack {
                    ScrollView(.horizontal, showsIndicators: false){
                        HStack(spacing: 20) {
                            ForEach(days.indices, id: \.self) { i in
                                CalendarView(
                                    number: days[i].number,
                                    days: days[i].weekday,
                                    color: days[i].isToday ? #colorLiteral(red: 0.9060331583, green: 0.2547450066, blue: 0.3359550834, alpha: 1) : #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1),
                                    textcolor: days[i].isToday ? #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) : #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
                                ).onTapGesture {
                                    selectedDay = i
                                    for j in days.indices {
                                        if j == i {
                                            days[i].isToday = true
                                        } else {
                                            days[j].isToday = false
                                        }
                                    }
                                }
                            }
                            
                        }
                        .padding(.leading,10)
                        .padding(.bottom, 10)
                        .shadow(radius: 3, x: 3, y: 3)
                    }
                }
            }
            Button(action: {
                if selectedDay < days.count-1 {
                    for j in days.indices { days[j].isToday = false }
                    days[selectedDay+1].isToday = true
                    selectedDay += 1
                    withAnimation { scrollProxy.scrollTo(selectedDay) }
                }
            }) {
                Image(systemName: "chevron.right.circle.fill")
            }
        }
    }
    .onAppear {
        getCurrentWeekdays()
    }
}
    
    func getCurrentWeekdays() {
        /// from https://stackoverflow.com/a/62355272/14351818
        let dateComponents = Calendar(identifier: .gregorian).dateComponents([.yearForWeekOfYear, .weekOfYear], from: Date())
        let startOfWeek = Calendar(identifier: .gregorian).date(from: dateComponents)!
        let startOfWeekNoon = Calendar(identifier: .gregorian).date(bySettingHour: 12, minute: 0, second: 0, of: startOfWeek)!
        
        days = (0...6).map {
            let calendar = Calendar(identifier: .gregorian)
            let date = calendar.date(byAdding: .day, value: $0, to: startOfWeekNoon)!
            
            let numberDateFormatter = DateFormatter()
            numberDateFormatter.dateFormat = "d"
            let number = numberDateFormatter.string(from: date)
            
            let weekdayDateFormatter = DateFormatter()
            weekdayDateFormatter.dateFormat = "E"
            let weekday = weekdayDateFormatter.string(from: date)
            
            let calendarDay = CalendarDay(
                number: number,
                weekday: weekday,
                isToday: calendar.component(.day, from: Date()) == calendar.component(.day, from: date)
            )
            //  <--- here --->
            if calendar.component(.day, from: Date()) == calendar.component(.day, from: date) {
                selectedDay = $0
            }
            
            return calendarDay
        }
        
    }
}
于 2021-06-09T10:25:23.267 回答