Hello together,
i want to us some classes to manage informations, which get fetched from a firestore database. My idea was, that I will have different classes for the different state of informations. The information which will be common for the different states should have the same properties. Therefore it made sense for me to have a super class which stores the main informations and derive a subclass with extra properties to store the more informations.
My question is, how to define the initializer method properly, so that I can store these data informations fetched from firestore at once without any loss.
Superclass (I reduced it to a minimum, just to show my principal problem):
class GameInfo: Codable, Identifiable {
@DocumentID var id: String? // -> UUID of firestore document
var league: String
var homeTeam: String
var guestTeam: String
enum CodingKeys: String, CodingKey {
case league
case homeTeam
case guestTeam
}
init(league: String, homeTeam: String, guestTeam: String) {
self.league = league
self.homeTeam = homeTeam
self.guestTeam = guestTeam
}
}
the subclass should contain the GameInfo Properties and some others ...
class Game: GameInfo {
var startTime: Date?
enum CodingKeys: String, CodingKey {
case startTime
}
init(league: String, homeTeam: String, guestTeam: String, startTime: Date) {
self.startTime = startTime
super.init(league: league, homeTeam: homeTeam, guestTeam: guestTeam)
}
required init(from decoder: any Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
self.startTime = try values.decodeIfPresent(Date.self, forKey: .startTime)
super.init(league: "", homeTeam: "",, guestTeam: "")
}
With the required init-method, informations get decoded and stored. (the data from firestore contain the league, homeTeam, guestTeam and startTime informations). The super.init() method as defined results in empty strings. But what I want is, that the league, homeTeam and guestTeam values will also be decoded from the firestore informations. But I don't know how. If I use the code
super.init(league: league, homeTeam: homeTeam, guestTeam: guestTeam)
within the required init() than I get the compiler error message
'self' used in property access 'league' before 'super.init' call
What is wrong in my thinking ? Any help appreciated.
Thanks and best regards
Peter
Post
Replies
Boosts
Views
Activity
Hello together,
does anyone know how I can scale a view to a given document size (e.g. A4: 210/297 mm) without scaling the view itself?
With enclosed code I can create the pdf-document, but the paperize is not the intended size. It is too big.
Variation this line of code
var mediaBox = CGRect(origin: .zero, size: CGSize(width: size.width, height: size.height))
into
var mediaBox = CGRect(origin: .zero, size: CGSize(width: 595, height: 842)
does not scale the view (it just shows a part of it at the correct papersize).
So what do I have to do to scale the rendered view to the proper size?
Enclosed a very simple code snipped to see th strange behavior.
Thx, best regards
Peter
import SwiftUI
struct ContentView: View {
var body: some View {
ZStack {
Rectangle()
.frame(width: 2100, height: 2910)
.foregroundColor(.red)
Rectangle()
.frame(width: 2100/2, height: 2910/3)
.foregroundColor(.blue)
Text("Hello, world!")
}
.padding()
.onAppear(perform: {
generatePDF()
})
}
// generate pdf from given view
@MainActor func generatePDF() -> URL {
// Select UI View to render as pdf
let image = ImageRenderer(content: ContentView())
let url = URL.documentsDirectory.appending(path: "generatedPDF.pdf")
image.render{ size, context in
var mediaBox = CGRect(origin: .zero, size: CGSize(width: size.width, height: size.height))
guard let consumer = CGDataConsumer(url: url as CFURL),
let pdfContext = CGContext(consumer: consumer, mediaBox: &mediaBox, nil)
else {
return
}
pdfContext.beginPDFPage(nil)
pdfContext.translateBy(x: mediaBox.size.width / 2 - size.width / 2,
y: mediaBox.size.height / 2 - size.height / 2)
context(pdfContext)
pdfContext.endPDFPage()
pdfContext.closePDF()
}
print("Saving PDF to \(url.path())")
return url
}
}
#Preview {
ContentView()
}
![]("https://developer.apple.com/forums/content/attachment/67b11ec8-af9e-4ab7-a0a5-0c020b7a45d4" "title=generatedPDF (without scaling).jpg;width=2652;height=2526")
![]("https://developer.apple.com/forums/content/attachment/b2c24a25-3805-4664-8adb-dcb81c3e96c4" "title=generatedPDF (with scaling).jpg;width=2132;height=1510")
Hello,
i had to found out, that I can’t call a view out of a ScrollView by tapping on an item of the scroll view. Enclosed minimal code show’s the effect. The tapping is recognized, but the view doesn’t switch to “AnotherView”.
Why is this the case? Works as designed or did I misunderstand something fundamental?
Any help appreciated.
Thx, Peter
import SwiftUI
struct ContentView: View {
var body: some View {
ScrollView{
VStack {
ForEach(0..<14) {value in
Text("Test \(value)")
.padding(.vertical)
.onTapGesture {
print("scrollview-item tapped")
AnotherView()
}
}
}
}
}
}
struct AnotherView: View {
var body: some View {
Text("Another View")
}
}
#Preview {
ContentView()
}
#Preview {
AnotherView()
}```