How to create like a multiple value Boolean in SwiftUI? - if-statement

Let say I have a SwiftUI component and I want it to change color according to a parameter I choose like :
Component(colorValue: "1")
Component(colorValue: "2")
Component(colorValue: "3")
colorValue: 1 would change the color of my component to red, 2 to green, 3 to blue for example.
When I only had 2 colors in the beggining of my project I used a boolean in my component :
Rectangle().fill(Color(colorValue ? "red" : "blue"))
But now that I have multiple choice, how can I achieve the color change by checking the value of the colorValue String ?
Thanks in advance !

just use a function
func getColorValue() -> Color {
if colorValue == 1 { return .red }
// and so on
}
Rectangle().fill(Color(getColorValue()))

Related

Change of listRowBackground in SwiftUI for NavigationLink doesn't change the full background

Code is the following:
List(selection: $selectedBoard) {
ForEach(boards) { board in
NavigationLink(tag: board, selection: $selectedBoard) {
BoardView(board: board)
} label: {
Text(board.name ?? "Board")
}
.listRowBackground(self.selectedBoard == board ? Color.App.boardSelection : Color.App.boardBackground)
The effect is the following:
See the gray space on the left and right? This is the accent color that I don't know how to remove. The whole row should be the same, uniform color of a bit lighter black.
Working example: https://github.com/igr/Clmn
https://github.com/igr/Clmn/blob/main/Clmn/Views/BoardList/BoardsNavigationListView.swift#L32
This happens when List is used in NavigationView for iteration of NavigationLink elements.
This seems to be a bug.

SwiftUI is there some way to get the background color of a List in light or dark mode?

Basically the background color of a list is this gray ish color from what I see, I wanna make some row background color to match the color of the List background in both light and dark mode so I was wondering if there was maybe some built in color like secondary or primary that might be able to just get the List background color but if there isn't what color is the List background color exactly in Light mode and how I can get a row background color to be that color when the device is in light mode and to be just straight black when it's in dark mode?
I had the exact same question. You have to set it via HEX-Value.
Add an extension that allows you to convert HEX to UIColor:
extension UIColor {
convenience init(hex: String, alpha: CGFloat = 1) {
assert(hex[hex.startIndex] == "#", "format expected: #rrggbb")
let scanner = Scanner(string: hex)
scanner.scanLocation = 1
var rgb: UInt32 = 0
scanner.scanHexInt32(&rgb)
self.init(
red: CGFloat((rgb & 0xFF0000) >> 16)/255.0,
green: CGFloat((rgb & 0xFF00) >> 8)/255.0,
blue: CGFloat((rgb & 0xFF) )/255.0,
alpha: alpha)
}
}
Make sure you can access colorScheme environment Variable. Insert this where you also have your #State variables:
#Environment(\.colorScheme) private var colorScheme
Put all your views in a VStack, so they are grouped together and add this modifiers to your new VStack:
.background(colorScheme == .light ? Color(uiColor: UIColor(hex: "#f2f2f7", alpha: 1)) : Color.black )
This is going to set the background to the color (#F2F2F7) if the device is set to light-mode
I hope I was able to help you!

Issue using Shape as type

I'm trying to create some simple funcs to create different shapes (diamond, rectangle and capsule) with different colors and different shading (filled, stroked and striped). To abstract some of the repetition away I've tried to pass the shape but get the dreaded "Protocol 'Shape' can only be used as a generic constraint because it has Self or associated type requirements". I've also tried passing an Int and using a Switch statement to recreate the shape in function but that has also not worked.
This function works for any color, but only one shape:
func stripedSymbol (_ solidColor: Color) -> some View {
let shape = Diamond()
return ZStack {
shape.fill(gradientFill(solidColor))
shape.stroke(solidColor)
}
}
Would like to be able to call the function with color AND shape (either directly or encoded in Int or enum) something like this:
func stripedSymbol (_ solidColor: Color, shape: Shape) -> some View {
return ZStack {
shape.fill(gradientFill(solidColor))
shape.stroke(solidColor)
}
}
Any suggestions?
Shape is self-referenced so it can only be used to add constraints. This should work:
func stripedSymbol<S: Shape> (_ solidColor: Color, shape: S) -> some View {
return ZStack {
shape.fill(gradientFill(solidColor))
shape.stroke(solidColor)
}
}

Changing a button background colour using RGB

Im sure that it will be a simple and obvious fix, but I cannot see why this occurs.
Basically I want to code a button to change its background colour, depending on what the colour is at the present. The following code works but it uses the UI Colours in xcode.
-(IBAction)Button1Colour:(id)sender{
if (_Button1.backgroundColor == nil) {
_Button1.backgroundColor = [UIColor orangeColor];}
else if (_Button1.backgroundColor == [UIColor orangeColor]) {
_Button1.backgroundColor = [UIColor greenColor];}
else (_Button1.backgroundColor = nil);}
Now if I use RGB colours as follows:
-(IBAction)Button1Colour:(id)sender{
if (_Button1.backgroundColor == nil) {
_Button1.backgroundColor = [UIColor colorWithRed:(216/255.f) green:(146/255.f) blue:(48/255.f) alpha:0.3];}
else if (_Button1.backgroundColor == [UIColor colorWithRed:(216/255.f) green:(146/255.f) blue:(48/255.f) alpha:0.3]) {
_Button1.backgroundColor = [UIColor colorWithRed:(33/255.f) green:(141/255.f) blue:(8/255.f) alpha:0.3];}
else (_Button1.backgroundColor = nil);}
The button will only cycle from nil to amber to nil etc missing out the else if statement.
Any advice or help would be much appreciated
You're trying to determine whether the button is a particular color by comparing 3 sets of floating point numbers.
The second if test is failing because you can't compare CGFloats for exact equality.
The easier way is to subclass your button and add a BOOL property indicating whether it's "toggled" or not. Then you can check the property and simply change between one color and the next.
Assuming the property you add is called green, it would look like this
#property (assign, getter=isGreen) BOOL green;
and you could more concisely change the color like so
Button1.backgroundColor = [Button1 isGreen] ? [UIColor orangeColor] : [UIColor greenColor];
Button1.green = !Button1.green;
As an aside, naming conventions suggest that a class starts with a capital letter, e.g. UIButton. An instance variable starts with a lowercase letter, e.g. button1.

Alpha component for object._colors in XTK

Is it possible to have Alpha component for object._colors ?
var object = new X.object();
var c = object._colors;
var color = new Array(4);
c.add(color[0], color[1], color[2], color[4]);//Is this Allowed ..?
I am having the R,G,B,A values in color. where R= Red, G= Green, B= Blue and A = transparency component.
Is it possible to allow transparency/Alpha component ?
X.object has an attribute "opacity" (varying between 0 and 1) implemented in the mixin "displayable", so to use it from inside the framework use object._opacity and from outside "object.opacity=;" or "var myvar = object.opacity;" (respectively the setter and getter for opacity).
Other property you can use is object._visible (boolean) to choose if you display it or not.
Ricola3D