I have a number of cute premade structs,
///Cute green flag icon
struct YahIcon: View {
var body: some View {
Image(systemName: "flag.checkered")
.symbolRenderingMode(.palette).foregroundStyle(.green)
.font(.system(size: 32, weight: .light))
.transformEffect(CGAffineTransform(rotationAngle: -0.3).translatedBy(x: -8, y: 7))
}
}
///Cute dotty box icon
struct NahIcon: View {
var body: some View {
Image(systemName: "square.dotted")
.symbolRenderingMode(.palette).foregroundStyle(.tertiary)
.font(.system(size: 32, weight: .medium))
}
}
which you can use freely in a View
///Cancelled sportsman
struct Dossier: View {
var data: MediaPersonality
var body: some View {
HStack {
Blah
NahIcon
Blah
Blah
}
}
}
Great.
Often for say text, I'll do some long calculation in a property up the top, rather than repetitively pasting it inside builder items.
struct Dossier: View {
var data: MediaPersonality
var descrip: String {
return(data.blah.lowercased() + " blah\(data.blah.blah) \(blah.count)")
}
var body: some View {
HStack {
Text(descrip)
NahIcon
Text(descrip)
Blah
}
}
}
All good.
However, when doing the same sort of decision making with images ...
struct Dossier: View {
var data: MediaPersonality
var body: some View {
HStack {
Blah
if (data.toggle == "Go") {
YahIcon.init()
.frame( etc
.frame( etc
}
else {
NahIcon.init()
.frame( etc
.frame( etc
}
Blah
Blah
}
}
}
it would be better to do something conceptually like THIS
struct Dossier: View {
var data: MediaPersonality
var CorrectIcon: View {
if (data.toggle == "Go") {
return (YahIcon.init()
.frame( etc
.frame( etc
)
}
else {
return (NahIcon.init()
.frame( etc
.frame( etc
)
}
}
var body: some View {
HStack {
Blah
CorrectIcon
Blah
Blah
VStack {
CorrectIcon
Blah
}
}
}
}
(Note - or perhaps better with the "frame etc" on the CorrectIcon inside the View rather than included in the property; either/both would be ideal.)
But of course that is meaningless, you can't do it.
The "View subclasses" YahIcon and NahIcon can and will be changed frequently and indeed conceptually by the design krew and they are used as-is repo wide, so adding a simple toggle inside them is not a plan.
So,
using a property in a View
, you can conveniently return (say) a string or numeric calculation for use inside one of the view items, no problem.
how can one "return" and use a View
as such, from such a calculation?
should the globally available example icons (YahIcon etc) perhaps be encapsulated in a different way to help with this issue?
superficially Xcode will tall you "use any View rather than View" however I can't get that to work by hacking around - perhaps I've just made a simple mistake?
How to?
I've seen similar questions but unfortunately nothing exactly answering this (seemingly basic?) issue. Perhaps I'm just missing something simple.
WTT @Sweeper the formula is:
struct PGATour: View {
var data: TasksItem
@ViewBuilder var KawaiiIcon: some View {
if (d.Status == .bail) {
YahIcon.init()
.frame(maxWidth: 44, alignment: .trailing)
}
else {
NahIcon.init()
.frame(maxWidth: 44, alignment: .trailing)
}
}
var body: some View {
HStack {
Text("example")
KawaiiIcon
Text("example")
}
}
where the "subclass -like" View
(see question) are
struct YahIcon: View {
var body: some View {
Image(systemName: "flag.checkered")
.etc
}
}
struct NahIcon: View {
var body: some View {
Image(systemName: "square.dotted")
.etc
}
}
///Also courtesy @Sweeper, a view with an initializer
struct ABIcon: View {
var good: Bool
var body: some View {
if good {
YahIcon.init()
}
else {
NahIcon.init()
}
}
}