SwiftUI: Difference between revisions
Jump to navigation
Jump to search
(83 intermediate revisions by the same user not shown) | |||
Line 26: | Line 26: | ||
} | } | ||
</source> | </source> | ||
==ContextMenu== | |||
<source lang="swift"> | |||
Text("Rails").contextMenu { | |||
Button(action: {}){ | |||
Text("LRT") | |||
Image(systemName: "globe") | |||
} | |||
Button(action: {}){ | |||
Text("MRT") | |||
Image(systemName: "location.circle") | |||
} | |||
} | |||
</source> | |||
==MyPDFView== | |||
<source lang="swift"> | |||
// MARK: - MyPDFView | |||
fileprivate struct MyPDFView: UIViewRepresentable { | |||
@Binding var data: Data | |||
func makeUIView(context: UIViewRepresentableContext<MyPDFView>) -> UIView { | |||
let empty = UIView() | |||
//guard let provider = CGDataProvider(data: self.data as CFData) else {return empty} | |||
//guard let document = CGPDFDocument(provider) else {return empty} | |||
guard let url = URL(string: "https://api.chorke.org/academia/api/v1.0/health/card/01890600.pdf") else {return empty} | |||
guard let document = CGPDFDocument(url as CFURL) else {return empty} | |||
guard let page = document.page(at: 1) else {return empty} | |||
let pageRect = page.getBoxRect(.mediaBox) | |||
let renderer = UIGraphicsImageRenderer(size: pageRect.size) | |||
let uiImage = renderer.image { ctx in | |||
UIColor.white.set() | |||
ctx.fill(pageRect) | |||
ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height) | |||
ctx.cgContext.scaleBy(x: 1.0, y: -1.0) | |||
ctx.cgContext.drawPDFPage(page) | |||
} | |||
let view = UIImageView(image: uiImage) | |||
view.contentMode = .scaleAspectFill | |||
return view | |||
} | |||
func updateUIView(_ view: UIView, context: UIViewRepresentableContext<MyPDFView>) { | |||
// MARK: - TODO | |||
} | |||
} | |||
</source> | |||
==MyKDCalendar== | |||
<source lang="swift"> | |||
MyKDCalendar().frame(minWidth: 200, minHeight: 350).background(ThemeColor.midnightBlue.color.opacity(0.5)).padding(.bottom, 20) | |||
</source> | |||
<source lang="swift"> | |||
import SwiftUI | |||
import KDCalendar | |||
public struct MyKDCalendar: UIViewRepresentable { | |||
@State var date:Date = .init() | |||
let gregorian: Calendar = .init(identifier: .gregorian) | |||
let secondary: UIColor = .parse(0xE0B355) | |||
let tersiary : UIColor = .parse(0xE7EEEF) | |||
let primary : UIColor = .parse(0x346C7C) | |||
public func makeUIView(context: Context) -> CalendarView { | |||
let style = self.getStyle(self.primary, self.secondary, self.tersiary) | |||
let calendar: CalendarView = .init() | |||
calendar.direction = .horizontal | |||
calendar.marksWeekends = true | |||
calendar.style = style | |||
calendar.setDisplayDate(date, animated: true) | |||
calendar.selectDate(date) | |||
calendar.dataSource = self | |||
calendar.delegate = self | |||
return calendar | |||
} | |||
public func updateUIView(_ calendar: CalendarView, context: Context) { | |||
calendar.selectDate(date) | |||
} | |||
} | |||
extension MyKDCalendar: CalendarViewDataSource { | |||
public func startDate() -> Date { | |||
return Date.init() | |||
} | |||
public func endDate() -> Date { | |||
return self.gregorian.date(byAdding: .month, value: 3, to: Date.init())! | |||
} | |||
public func headerString(_ date: Date) -> String? { | |||
return nil | |||
} | |||
private func getStyle(_ primary: UIColor, _ secondary: UIColor, _ tersiary: UIColor) -> CalendarView.Style { | |||
let style: CalendarView.Style = .init() | |||
style.cellSelectedBorderColor = secondary | |||
style.cellSelectedTextColor = tersiary | |||
style.cellSelectedColor = secondary | |||
style.firstWeekday = .sunday | |||
style.weekdaysBackgroundColor = primary | |||
style.headerBackgroundColor = primary | |||
style.weekdaysTextColor = tersiary | |||
style.headerTextColor = tersiary | |||
style.cellTextColorWeekend = secondary | |||
style.cellTextColorDefault = primary | |||
style.cellTextColorToday = tersiary | |||
style.cellColorOutOfRange = .systemGray | |||
style.cellColorDefault = tersiary | |||
style.cellColorToday = primary | |||
return style | |||
} | |||
} | |||
extension MyKDCalendar: CalendarViewDelegate { | |||
public func calendar(_ calendar: CalendarView, didDeselectDate date: Date) {} | |||
public func calendar(_ calendar: CalendarView, didScrollToMonth date: Date) {} | |||
public func calendar(_ calendar: CalendarView, didSelectDate date: Date, withEvents events: [CalendarEvent]) {} | |||
public func calendar(_ calendar: CalendarView, didLongPressDate date: Date, withEvents events: [CalendarEvent]?) {} | |||
public func calendar(_ calendar: CalendarView, canSelectDate date: Date) -> Bool { | |||
return true | |||
} | |||
} | |||
</source> | |||
==MyFSCalendar== | |||
<source lang="swift"> | |||
MyFSCalendar().frame(minWidth: 200, minHeight: 320).padding(.leading, 5) | |||
</source> | |||
<source lang="swift"> | |||
import SwiftUI | |||
import FSCalendar | |||
struct MyFSCalendar: UIViewControllerRepresentable { | |||
func makeUIViewController(context: UIViewControllerRepresentableContext<MyFSCalendar>) -> MyFSCalendarController { | |||
let calendar: MyFSCalendarController = .init() | |||
return calendar | |||
} | |||
func updateUIViewController(_ calendar: MyFSCalendarController, context: UIViewControllerRepresentableContext<MyFSCalendar>) { | |||
// MARK: - TODO | |||
} | |||
} | |||
</source> | |||
<source lang="swift"> | |||
import UIKit | |||
import FSCalendar | |||
class MyFSCalendarController: UIViewController, FSCalendarDelegateAppearance { | |||
let secondary: UIColor = .parse(0xE0B355) | |||
let tersiary : UIColor = .parse(0xE7EEEF) | |||
let primary : UIColor = .parse(0x346C7C) | |||
fileprivate let formatter: DateFormatter = { | |||
let formatter = DateFormatter() | |||
formatter.dateFormat = "yyyy-MM-dd" | |||
return formatter | |||
}() | |||
fileprivate weak var calendar: FSCalendar! | |||
override func loadView() { | |||
let width: CGFloat = UIScreen.main.bounds.width - 40 | |||
let frame: CGRect = .init(x: 0, y: 0, width: width, height: 300) | |||
let view: UIView = .init(frame: frame) | |||
self.view = view | |||
let calendar: FSCalendar = .init(frame: frame) | |||
calendar.allowsMultipleSelection = false | |||
calendar.dataSource = self | |||
calendar.delegate = self | |||
view.addSubview(calendar) | |||
self.calendar = calendar | |||
calendar.calendarHeaderView.backgroundColor = self.primary | |||
calendar.calendarWeekdayView.backgroundColor = self.primary | |||
calendar.appearance.headerTitleColor = self.tersiary | |||
calendar.appearance.weekdayTextColor = self.tersiary | |||
calendar.appearance.eventSelectionColor = self.tersiary | |||
calendar.appearance.eventDefaultColor = self.primary | |||
calendar.appearance.eventOffset = CGPoint(x: 0, y: -7) | |||
calendar.appearance.todaySelectionColor = self.primary | |||
calendar.appearance.selectionColor = self.secondary | |||
calendar.appearance.todayColor = self.primary | |||
calendar.appearance.titleWeekendColor = self.secondary | |||
calendar.appearance.titleDefaultColor = self.primary | |||
calendar.swipeToChooseGesture.isEnabled = true | |||
let scopeGesture = UIPanGestureRecognizer(target: calendar, action: #selector(calendar.handleScopeGesture(_:))); | |||
scopeGesture.delegate = self | |||
calendar.addGestureRecognizer(scopeGesture) | |||
} | |||
override func viewDidLoad() { | |||
super.viewDidLoad() | |||
self.calendar.scope = .month | |||
self.calendar.select(Date.init()) | |||
self.calendar.accessibilityIdentifier = "calendar" | |||
} | |||
} | |||
extension MyFSCalendarController: FSCalendarDataSource { | |||
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) { | |||
debugPrint("did select date \(self.formatter.string(from: date))") | |||
let selectedDates = calendar.selectedDates.map({self.formatter.string(from: $0)}) | |||
debugPrint("selected dates is \(selectedDates)") | |||
if monthPosition == .next || monthPosition == .previous { | |||
calendar.setCurrentPage(date, animated: true) | |||
} | |||
} | |||
} | |||
extension MyFSCalendarController: FSCalendarDelegate { | |||
func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) { | |||
self.calendar.frame.size.height = bounds.height | |||
self.view.layoutIfNeeded() | |||
} | |||
} | |||
extension MyFSCalendarController: UIGestureRecognizerDelegate { | |||
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { | |||
debugPrint("UIGestureRecognizer") | |||
return true | |||
} | |||
} | |||
</source> | |||
==Singleton== | |||
<source lang="swift"> | |||
class NetworkManager { | |||
let baseURL: URL | |||
private init(baseURL: URL) { | |||
self.baseURL = baseURL | |||
} | |||
// MARK: - sharedNetworkManager | |||
private static var sharedNetworkManager: NetworkManager = { | |||
let networkManager = NetworkManager(baseURL: API.baseURL) | |||
return networkManager | |||
}() | |||
// MARK: - shared | |||
class func shared() -> NetworkManager { | |||
return Self.sharedNetworkManager | |||
} | |||
} | |||
</source> | |||
==State Variable== | |||
<source lang="swift"> | |||
import SwiftUI | |||
struct StateInitView: View { | |||
@State var isBusy: Bool = false | |||
var title: String | |||
init(_ title: String,_ isBusy: Bool = false) { | |||
self._isBusy = State(initialValue: isBusy) | |||
self.title = title | |||
} | |||
var body: some View { | |||
ZStack { | |||
if (self.isBusy){ | |||
Text("Baking your cake!") | |||
} else { | |||
Text("Collect your cake.") | |||
} | |||
} | |||
} | |||
} | |||
</source> | |||
==Binding Variable== | |||
<source lang="swift"> | |||
struct MyCheckGroup: View { | |||
@Binding var group : [ResourceLabel] | |||
var action: ((ResourceLabel) -> Void)? = nil | |||
var body: some View { | |||
HStack(alignment: .top, spacing: 20) { | |||
ForEach(Array(self.group.enumerated()), id: \.offset) { index, model in | |||
MyCheckBox(model: .constant(model), action: self.action) | |||
} | |||
} | |||
} | |||
} | |||
struct MyCheckBox: View { | |||
@Binding var model: ResourceLabel | |||
var action: ((ResourceLabel) -> Void)? = nil | |||
var body: some View { | |||
//TODO | |||
} | |||
} | |||
</source> | |||
==For Each== | |||
{| | |||
| valign="top" | | |||
'''Id:''' | |||
<source lang="swift"> | |||
ForEach(self.labels, id: \.id) { label in | |||
AccordionItem(label: label){ label in | |||
self.addAccordionView(label) | |||
} | |||
} | |||
</source> | |||
| valign="top" | | |||
'''Offset:''' | |||
<source lang="swift"> | |||
ForEach(Array(self.labels.enumerated()), id: \.offset) { index, label in | |||
AccordionItem(label: label){ label in | |||
self.addAccordionView(label) | |||
} | |||
} | |||
</source> | |||
|} | |||
==References== | ==References== | ||
Line 80: | Line 412: | ||
{| | {| | ||
| valign="top" | | | valign="top" | | ||
* [https://stackoverflow.com/questions/56819063 UIHostingController inside an UIView] | |||
* [https://medium.com/better-programming/using-the-preferencekey-protocol-to-align-views-7f3ae32f60fc Using the PreferenceKey Protocol] | |||
* [https://www.raywenderlich.com/4503153-how-to-create-a-splash-screen-with-swiftui Splash Screen With SwiftUI] | |||
* [https://stackoverflow.com/questions/56631892 Add a SwiftUI View to UIKit] | |||
* [https://swiftwithmajid.com/2020/01/15/the-magic-of-view-preferences-in-swiftui/ SwiftUI Preferences] | |||
* [https://jinxiansen.github.io/SwiftUI/ SwiftUI Example] | |||
* [https://www.hackingwithswift.com/quick-start/swiftui/how-to-show-a-context-menu Context Menu] | |||
* [https://stackoverflow.com/questions/58580027 Radio Group] | * [https://stackoverflow.com/questions/58580027 Radio Group] | ||
* [https://makeapppie.com/2019/10/16/checkboxes-in-swiftui/ CheckBox] | * [https://makeapppie.com/2019/10/16/checkboxes-in-swiftui/ CheckBox] | ||
* [https://github.com/andreamazz/AMPopTip Tool Tips] | |||
| valign="top" | | |||
* [https://www.hackingwithswift.com/quick-start/swiftui/how-to-place-content-outside-the-safe-area Place View outside of the Safe Area] | |||
* [https://stackoverflow.com/questions/56760335 SwiftUI Round Specific Corners] | |||
* [https://stackoverflow.com/questions/56496638 Activity indicator in SwiftUI] | |||
* [https://stackoverflow.com/questions/26028918 iPhone/iPad Device Model] | |||
* [https://ryanashcraft.me/swiftui-programmatic-navigation/ Programmatic Navigation] | |||
* [https://stackoverflow.com/questions/56726663 Add a TextField to Alert] | |||
* [https://stackoverflow.com/questions/59150320 TextField Font Weight] | |||
* [https://github.com/SimpleBoilerplates/SwiftUI-Cheat-Sheet SwiftUI Cheat Sheet] | |||
* [https://stackoverflow.com/questions/56610957 Blur a background] | |||
* [https://stackoverflow.com/questions/58121756 Return Key] | |||
| valign="top" | | |||
* [https://stackoverflow.com/questions/56938805/how-to-pass-one-swiftui-view-as-a-variable-to-another-view-struct SwiftUI View as a variable to another View] | |||
* [https://stackoverflow.com/questions/56645647 Dynamic List of Views using SwiftUI] | |||
* [https://stackoverflow.com/questions/28124684 Generic type conforms to Protocol] | |||
* [https://www.amerhukic.com/finding-the-custom-url-scheme-of-an-ios-app Finding the custom URL scheme] | |||
* [https://www.objc.io/blog/2019/06/25/swiftui-data-loading/ Loading Data Asynchronously] | |||
* [https://stackoverflow.com/questions/56691630 <code>@State</code> variable initialization] | |||
* [https://stackoverflow.com/questions/57415086 Passing data between Views] | |||
* [http://www.appsdeveloperblog.com/http-post-request-example-in-swift POST Request Example] | |||
* [https://forums.raywenderlich.com/t/today-extension-tutorial-getting-started/27584 URL Scheme Extension] | |||
* [https://stackoverflow.com/questions/56736466/ Alternative to switch] | |||
|} | |||
----- | |||
{| | |||
| valign="top" | | |||
* [https://www.hackingwithswift.com/quick-start/swiftui/whats-the-difference-between-observedobject-state-and-environmentobject <code>@ObservedObject</code>, <code>@State</code> vs. <code>@EnvironmentObject</code>] | |||
* [https://stackoverflow.com/questions/54971163 Set environment variable <code>CG_PDF_VERBOSE</code>] | |||
* [https://www.hackingwithswift.com/books/ios-swiftui/wrapping-a-uiviewcontroller-in-a-swiftui-view Wrapping a UIViewController in a SwiftUI] | |||
* [https://medium.com/codespace69/xcode-10-xcode-11-2-x-error-multiple-commands-produce-4e5ab75558f2 Error: Multiple commands produce] | |||
* [https://stackoverflow.com/questions/748175 Asynchronous vs Synchronous] | |||
* [https://www.hackingwithswift.com/books/ios-swiftui/working-with-identifiable-items-in-swiftui Identifiable items in SwiftUI] | |||
* [https://stackoverflow.com/questions/24031621 Convert String to Double] | |||
* [https://github.com/Dalodd/Alamofire-Synchronous Alamofire Synchronous] | |||
* [https://stackoverflow.com/questions/30930223 Adjust alpha of UIColor] | |||
* [https://github.com/mmick66/CalendarView KDCalendar] | |||
| valign="top" | | |||
* [https://www.hackingwithswift.com/example-code/system/how-to-run-code-after-a-delay-using-asyncafter-and-perform After Delay <code>asyncAfter()</code> and <code>perform()</code>] | |||
* [https://medium.com/swift2go/writing-cleaner-asynchronous-code-in-swift-using-promise-pattern-f608254a349c Cleaner Asynchronous Code Using Promise] | |||
* [https://stackoverflow.com/questions/56505043 Dynamic View width of another View] | |||
* [https://stackoverflow.com/questions/57681885 Get Current Location using SwiftUI] | |||
* [https://stackoverflow.com/questions/57305372 Picker Selection by using Tag] | |||
* [https://cocoacasts.com/what-is-a-singleton-and-how-to-create-one-in-swift Singleton Object In Swift] | |||
* [https://fuckingswiftui.com/ Postmortem of SwiftUI] | |||
* [https://www.thetopsites.net/article/52447981.shtml Padding a Swift String] | |||
* [https://theswiftdev.com/promises-in-swift-for-beginners/ Promises in Swift] | |||
* [https://zonneveld.dev/swiftui-form/ SwiftUI Form] | |||
|} | |||
----- | |||
{| | |||
| valign="top" | | |||
* [https://stackoverflow.com/questions/44575293 JSONDecoder use a default value instead of Optional] | |||
* [https://stackoverflow.com/questions/56658558 Bind a grid of buttons of same width and height] | |||
* [https://swiftui-lab.com/communicating-with-the-view-tree-part-1/ Inspecting the View Tree by PreferenceKey] | |||
* [https://www.hackingwithswift.com/books/ios-swiftui/triggering-events-repeatedly-using-a-timer Triggering events repeatedly using a Timer] | |||
* [https://stackoverflow.com/questions/57134259 Deprecation of <code>keyWindow</code> in iOS 13.0] | |||
* [https://stackoverflow.com/questions/56505043 Bind the view the size of another view] | |||
* [https://swiftui-lab.com/geometryreader-to-the-rescue/ GeometryReader to the Rescue] | |||
* [https://stackoverflow.com/questions/56997725 Same Width Views in List Rows] | |||
* [https://stackoverflow.com/questions/56474019 How to change ListStyle in List] | |||
* [https://stackoverflow.com/questions/56685964 SwiftUI <code>@Binding</code> Initialise] | |||
| valign="top" | | |||
* [https://stackoverflow.com/questions/59404039/ Play audio using AVAudioPlayer in SwiftUI] | |||
* [https://medium.com/@mattoakes/a-better-way-to-automatically-merge-changes-in-your-xcode-project-files-3d83b3583fe4 Automatically Merge XCode Project] | |||
* [https://stackoverflow.com/questions/25736470/ Play sound when press a button] | |||
* [https://stackoverflow.com/questions/57153729/ Audio not playing in SwiftUI] | |||
* [https://medium.com/macoclock/how-to-use-webkit-webview-in-swiftui-4b944d04190a WebKit WebView in SwiftUI] | |||
* [https://stackoverflow.com/questions/34563329/how-to-play-mp3-audio-from-url-in-ios-swift/50991478 Play MP3 Audio from URL] | |||
|} | |} |
Latest revision as of 21:38, 30 September 2020
ContentView
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding()
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
ContextMenu
Text("Rails").contextMenu {
Button(action: {}){
Text("LRT")
Image(systemName: "globe")
}
Button(action: {}){
Text("MRT")
Image(systemName: "location.circle")
}
}
MyPDFView
// MARK: - MyPDFView
fileprivate struct MyPDFView: UIViewRepresentable {
@Binding var data: Data
func makeUIView(context: UIViewRepresentableContext<MyPDFView>) -> UIView {
let empty = UIView()
//guard let provider = CGDataProvider(data: self.data as CFData) else {return empty}
//guard let document = CGPDFDocument(provider) else {return empty}
guard let url = URL(string: "https://api.chorke.org/academia/api/v1.0/health/card/01890600.pdf") else {return empty}
guard let document = CGPDFDocument(url as CFURL) else {return empty}
guard let page = document.page(at: 1) else {return empty}
let pageRect = page.getBoxRect(.mediaBox)
let renderer = UIGraphicsImageRenderer(size: pageRect.size)
let uiImage = renderer.image { ctx in
UIColor.white.set()
ctx.fill(pageRect)
ctx.cgContext.translateBy(x: 0.0, y: pageRect.size.height)
ctx.cgContext.scaleBy(x: 1.0, y: -1.0)
ctx.cgContext.drawPDFPage(page)
}
let view = UIImageView(image: uiImage)
view.contentMode = .scaleAspectFill
return view
}
func updateUIView(_ view: UIView, context: UIViewRepresentableContext<MyPDFView>) {
// MARK: - TODO
}
}
MyKDCalendar
MyKDCalendar().frame(minWidth: 200, minHeight: 350).background(ThemeColor.midnightBlue.color.opacity(0.5)).padding(.bottom, 20)
import SwiftUI
import KDCalendar
public struct MyKDCalendar: UIViewRepresentable {
@State var date:Date = .init()
let gregorian: Calendar = .init(identifier: .gregorian)
let secondary: UIColor = .parse(0xE0B355)
let tersiary : UIColor = .parse(0xE7EEEF)
let primary : UIColor = .parse(0x346C7C)
public func makeUIView(context: Context) -> CalendarView {
let style = self.getStyle(self.primary, self.secondary, self.tersiary)
let calendar: CalendarView = .init()
calendar.direction = .horizontal
calendar.marksWeekends = true
calendar.style = style
calendar.setDisplayDate(date, animated: true)
calendar.selectDate(date)
calendar.dataSource = self
calendar.delegate = self
return calendar
}
public func updateUIView(_ calendar: CalendarView, context: Context) {
calendar.selectDate(date)
}
}
extension MyKDCalendar: CalendarViewDataSource {
public func startDate() -> Date {
return Date.init()
}
public func endDate() -> Date {
return self.gregorian.date(byAdding: .month, value: 3, to: Date.init())!
}
public func headerString(_ date: Date) -> String? {
return nil
}
private func getStyle(_ primary: UIColor, _ secondary: UIColor, _ tersiary: UIColor) -> CalendarView.Style {
let style: CalendarView.Style = .init()
style.cellSelectedBorderColor = secondary
style.cellSelectedTextColor = tersiary
style.cellSelectedColor = secondary
style.firstWeekday = .sunday
style.weekdaysBackgroundColor = primary
style.headerBackgroundColor = primary
style.weekdaysTextColor = tersiary
style.headerTextColor = tersiary
style.cellTextColorWeekend = secondary
style.cellTextColorDefault = primary
style.cellTextColorToday = tersiary
style.cellColorOutOfRange = .systemGray
style.cellColorDefault = tersiary
style.cellColorToday = primary
return style
}
}
extension MyKDCalendar: CalendarViewDelegate {
public func calendar(_ calendar: CalendarView, didDeselectDate date: Date) {}
public func calendar(_ calendar: CalendarView, didScrollToMonth date: Date) {}
public func calendar(_ calendar: CalendarView, didSelectDate date: Date, withEvents events: [CalendarEvent]) {}
public func calendar(_ calendar: CalendarView, didLongPressDate date: Date, withEvents events: [CalendarEvent]?) {}
public func calendar(_ calendar: CalendarView, canSelectDate date: Date) -> Bool {
return true
}
}
MyFSCalendar
MyFSCalendar().frame(minWidth: 200, minHeight: 320).padding(.leading, 5)
import SwiftUI
import FSCalendar
struct MyFSCalendar: UIViewControllerRepresentable {
func makeUIViewController(context: UIViewControllerRepresentableContext<MyFSCalendar>) -> MyFSCalendarController {
let calendar: MyFSCalendarController = .init()
return calendar
}
func updateUIViewController(_ calendar: MyFSCalendarController, context: UIViewControllerRepresentableContext<MyFSCalendar>) {
// MARK: - TODO
}
}
import UIKit
import FSCalendar
class MyFSCalendarController: UIViewController, FSCalendarDelegateAppearance {
let secondary: UIColor = .parse(0xE0B355)
let tersiary : UIColor = .parse(0xE7EEEF)
let primary : UIColor = .parse(0x346C7C)
fileprivate let formatter: DateFormatter = {
let formatter = DateFormatter()
formatter.dateFormat = "yyyy-MM-dd"
return formatter
}()
fileprivate weak var calendar: FSCalendar!
override func loadView() {
let width: CGFloat = UIScreen.main.bounds.width - 40
let frame: CGRect = .init(x: 0, y: 0, width: width, height: 300)
let view: UIView = .init(frame: frame)
self.view = view
let calendar: FSCalendar = .init(frame: frame)
calendar.allowsMultipleSelection = false
calendar.dataSource = self
calendar.delegate = self
view.addSubview(calendar)
self.calendar = calendar
calendar.calendarHeaderView.backgroundColor = self.primary
calendar.calendarWeekdayView.backgroundColor = self.primary
calendar.appearance.headerTitleColor = self.tersiary
calendar.appearance.weekdayTextColor = self.tersiary
calendar.appearance.eventSelectionColor = self.tersiary
calendar.appearance.eventDefaultColor = self.primary
calendar.appearance.eventOffset = CGPoint(x: 0, y: -7)
calendar.appearance.todaySelectionColor = self.primary
calendar.appearance.selectionColor = self.secondary
calendar.appearance.todayColor = self.primary
calendar.appearance.titleWeekendColor = self.secondary
calendar.appearance.titleDefaultColor = self.primary
calendar.swipeToChooseGesture.isEnabled = true
let scopeGesture = UIPanGestureRecognizer(target: calendar, action: #selector(calendar.handleScopeGesture(_:)));
scopeGesture.delegate = self
calendar.addGestureRecognizer(scopeGesture)
}
override func viewDidLoad() {
super.viewDidLoad()
self.calendar.scope = .month
self.calendar.select(Date.init())
self.calendar.accessibilityIdentifier = "calendar"
}
}
extension MyFSCalendarController: FSCalendarDataSource {
func calendar(_ calendar: FSCalendar, didSelect date: Date, at monthPosition: FSCalendarMonthPosition) {
debugPrint("did select date \(self.formatter.string(from: date))")
let selectedDates = calendar.selectedDates.map({self.formatter.string(from: $0)})
debugPrint("selected dates is \(selectedDates)")
if monthPosition == .next || monthPosition == .previous {
calendar.setCurrentPage(date, animated: true)
}
}
}
extension MyFSCalendarController: FSCalendarDelegate {
func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) {
self.calendar.frame.size.height = bounds.height
self.view.layoutIfNeeded()
}
}
extension MyFSCalendarController: UIGestureRecognizerDelegate {
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
debugPrint("UIGestureRecognizer")
return true
}
}
Singleton
class NetworkManager {
let baseURL: URL
private init(baseURL: URL) {
self.baseURL = baseURL
}
// MARK: - sharedNetworkManager
private static var sharedNetworkManager: NetworkManager = {
let networkManager = NetworkManager(baseURL: API.baseURL)
return networkManager
}()
// MARK: - shared
class func shared() -> NetworkManager {
return Self.sharedNetworkManager
}
}
State Variable
import SwiftUI
struct StateInitView: View {
@State var isBusy: Bool = false
var title: String
init(_ title: String,_ isBusy: Bool = false) {
self._isBusy = State(initialValue: isBusy)
self.title = title
}
var body: some View {
ZStack {
if (self.isBusy){
Text("Baking your cake!")
} else {
Text("Collect your cake.")
}
}
}
}
Binding Variable
struct MyCheckGroup: View {
@Binding var group : [ResourceLabel]
var action: ((ResourceLabel) -> Void)? = nil
var body: some View {
HStack(alignment: .top, spacing: 20) {
ForEach(Array(self.group.enumerated()), id: \.offset) { index, model in
MyCheckBox(model: .constant(model), action: self.action)
}
}
}
}
struct MyCheckBox: View {
@Binding var model: ResourceLabel
var action: ((ResourceLabel) -> Void)? = nil
var body: some View {
//TODO
}
}
For Each
Id: ForEach(self.labels, id: \.id) { label in
AccordionItem(label: label){ label in
self.addAccordionView(label)
}
}
|
Offset: ForEach(Array(self.labels.enumerated()), id: \.offset) { index, label in
AccordionItem(label: label){ label in
self.addAccordionView(label)
}
}
|