Problems with storyboard colors in mixed objective-c/swift project - xcode

I added a new view controller to my objective-c project. The new view controller is written in Swift. Everything compiles correctly and functions correctly except that no matter what color I choose for the view's background color, it either comes out white (default) or black. If I decrease the alpha for the default background color it just gets gray. If I have anything over about 0.4 alpha for any other color the view is black.
Second problem: the code in my Swift view controller to set background color for the view appears to have no effect. Relevant code is below. I first set the view background color to white with alpha 1.0 and then change it to the color I want. None of this has any effect. Is this because it has already been set in the storyboard? If so, how can I override the storyboard settings programmatically? I am very new to Swift but have been programming objective-c for about one year and I haven't seen this kind of problem in a pure objective-c project. Xcode version is 7.3.
I would really appreciate any help.
override func viewDidLoad() {
super.viewDidLoad()
self.username.delegate = self;
self.password.delegate = self;
self.navigationItem.setHidesBackButton(true, animated:true);
view.backgroundColor = UIColor(white: 0x255/255, alpha: 1.0)
//set the background color to blue-green
view.backgroundColor = UIColor(
red: 0x00/255,
green: 0x7d/255,
blue: 0x96/255,
alpha: 1.0)

It looks like these problems are due to auto layout problems. If there are any autolayout issues (even if they are not flagged by a red arrow in the project navigator), the storyboard produces a black screen. I'm not sure why this happens with Swift: objective-C would just produce a screen with some layout problems. Once all the autolayout issues get fixed (usually by using Reset to Suggested Constraints), there isn't a black screen. Also, my code for setting the screen background color then works.This was very frustrating and I don't know why it works this way when the code underlying the view is Swift and not objective-C. But if there is the tiniest variation in the storyboard scene that has a tiny autolayout problem, I get a black screen.

Related

Why does my NSBox draw a background? (boxType = .primary)

I realized that suddenly (without me touching the corresponding code) my NSBox has a double visualization. It is as if the Box has a background color and draws its normal rounded frame inside. I added a small screenshot. The parent control is white, the NSBox is gray with the title "Inputs" (unchanged titlePosition). Under the title is the normal box, adding a 2nd shade of gray.
I did not change any of the usual suspects, especially not boxType which is still set to .primary.
I did work on the Dark Mode (Dark Aqua) but cannot see any change that would cause this behaviour. effectiveAppearance is still Aqua.
A NSBox with a boxType of .primary always draws a background. That is intended behaviour. Only if the view behind NSBox is white you may not see it. If you want a NSBox without background you must make it boxType .custom and set the background color as required.

tvOS: Rounded corners for image view when focused

I have an image view that will get this awesome tvOS focus effect when the containing view gets focused.
The problem is - it should have rounded corners. Now this is easily done:
imageView.layer.cornerRadius = 5
imageView.layer.masksToBounds = true
I have to set either masksToBounds of the layer or clipsToBounds of the image view to true (which is basically the same), in order to clip the edges of the image - but as soon as I do this, the focus effect won't work any more, because it will get clipped as well.
I had more or less the same problem with buttons, but since the focus effect is much simpler than for the image view (only scaling and shadow), I just implemented it myself, but that is not an option for the image view, with all the effects applied (moving, shimmering, and so on...)
Is there an easier way? Did I miss something? I can't be the only trying to figure out how this works!? :)
I have found out an alternative solution. What one may do is to actually draw the image, clipping out the corners with an alpha channel. The image then gets scaled correctly when focused. That applied to the layer. Then, to have the alpha channel added to the other layers (like the one for the glowing effect) we need to set; "masksFocusEffectToContents = true".
I made an extension for it, based on this answer:
Swift 4.2
extension UIImageView {
func roundedImage(corners: UIRectCorner, radius: CGFloat) {
let rect = CGRect(origin:CGPoint(x: 0, y: 0), size: self.frame.size)
UIGraphicsBeginImageContextWithOptions(self.frame.size, false, 1)
UIBezierPath(
roundedRect: rect,
byRoundingCorners: corners,
cornerRadii: CGSize(width: radius, height: radius)
).addClip()
self.draw(rect)
self.image = UIGraphicsGetImageFromCurrentImageContext()!
// Shadows - Change shadowOpacity to value > 0 to enable the shadows
self.layer.shadowOpacity = 0
self.layer.shadowColor = UIColor.black.cgColor
self.layer.shadowOffset = CGSize(width: 10, height: 15)
self.layer.shadowRadius = 3
// This propagate the transparency to the the overlay layers,
// like the one for the glowing effect.
self.masksFocusEffectToContents = true
}
}
Then to apply the rounded corners call:
myImageView.adjustsImageWhenAncestorFocused = true
myImageView.clipToBounds = false
// masks all corners with a radius of 25 in myImageView
myImageView.roundedImage(corners: UIRectCorner.allCorners, radius: 25)
One can obviously modify roundedImage() to add the parameters to define the shadows at the calling time.
Downsides:
Borders behave like cornerRadius (they get drawn inside the image).
But I think I made it working somewhere, then investigating further I
lost the changes
I am not exactly sure this is the right way to do it. I am quite confident there must be some methods out there doing it in a couple of lines. In tvOS 11 Apple introduced the round badges (animatable and all), shown at WWDC 2017. I just can't find a sample for them.
Otherwise, tvOS 12 (beta for now) introduced the Lockup. I managed to implement them programmatically, as shown in this answer.
https://forums.developer.apple.com/thread/20513
We are also facing this same issue. When you round the corners, you can see the "shine" still has a rectange shape.
I showed the issue to the Dev Evangelists at the Tech Talks in Toronto and they said it's a bug. It's reported and open rdar://23846376
For 2022.
Note that you can just use UICardView on tvOS for the effect.
Simply put the UIImageView inside the card view.
Don't forget to actually turn OFF "adjust on ancestor focus" and "user interaction enabled" on the image view, or else it will "doubly expand" when the card view expands!
There's also a weird issue where you have to add 20 to the height of all card views to make them work neatly with and enclosed image view.

Change Xcode's storyboard interface builder canvas colour

I am using Xcode 6.4 and find the canvas/background colour of the interface builder to be terrible. ViewControllers have a general whitish colour, so does the canvas. It makes viewing rather uncomfortable as there is no contrast between the canvas and the objects I work with (view controllers etc). Is there any way I could change the canvas colour please?
As far as my research into this went, there is no way to change the canvas colour.
UPDATE
There seems to indeed be a way to do this (thanks to deej): here is a link

How do I get my Cocoa app to draw exactly the color specified by my designer in Sketch?

My designer has specified a color to draw. When I try to draw that color in a Cocoa app, I get a resulting color that’s visibly different from the reference image as displayed by Sketch.app.
I made a small Cocoa app that draws a custom view. Here’s the interesting part of the code. Note that I am initializing the color in SRGB space.
class View: NSView {
override func drawRect(dirtyRect: NSRect) {
let components : [CGFloat] = [156.0/255.0, 0, 254.0/255.0, 1]
let color = NSColor.init(SRGBRed: components[0], green: components[1], blue: components[2], alpha: components[3])
color.setFill()
NSRectFill(self.bounds)
}
}
Here’s what it draws. (Nevermind the part about the cursor. And I removed the window shadow so it would be easier to review this side by side with other windows.)
And here’s the Sketch file portion:
Putting it all together, here’s a side by side of the Sketch file and the custom view, as well as Xscope loupe displaying the color value under the mouse cursor.
When hovering over Sketch file, I see this:
When hovering over my custom view, I see this:
You can see that the color value of the pixel under the black mouse cursor as read by Xscope is significantly different. The colors also look significantly different on my Retina Macbook Pro display, though interestingly, not so different in the captured screenshot PNG.
HOWEVER: so far, this was all done with default display settings and color profile “Color LCD” (the hardware is Retina Macbook Pro with its built-in display). When I manually change the display profile to “sRGB IEC61966-2.1” in OSX Settings app, and then sample the colors again with Xscope, you can see these sampled values:
And when sampling the custom view:
Most interestingly, you can see that the values sampled by Xscope on my custom view exactly match the specified values, and the color is also visually correct. But of course, I can’t make my users change their display profile.
My question: how do I make my custom view color exactly match the color in Sketch (both for visual inspection and when sampled with the Xscope loupe) with the default Color LCD display profile?
Just worked through this issue myself. Here's my process. Just tested on a Retina Macbook Pro.
Open Sketch.
Open Digital Color Meter (installed on OSX)
Switch to 'Display in Generic RGB'
In menu, ensure that 'View -> Display Values -> As Decimal`
Mouse over your color of the artwork in sketch and note the values (e.g. 0, 150, 200)
Use that value in Cocoa:
-(void)drawRect:(NSRect)dirtyRect {
[[NSColor colorWithCalibratedRed:0/255.0 green:150/255.0 blue:200/255.0 alpha:1] set];
NSRectFill(self.bounds);
}
This should work, as 'Generic RGB' is a device independent space equivalent to the 'calibrated' color space in Cocoa.

How do you create a semi-transparent background for a UIView?

I am creating a UIView containing some text that partially covers a UIImageView. I want the user to be able to read the text and still maintain a perspective on the image underneath. I have tried setting the background color to [UIColor clearColor], but then the background is totally transparent and it is hard to read the text depending upon the image colors.
If I lower the view.alpha=0.5 the whole view including the text is partially transparent. What I'd like is to maintain the text and reduce the transparency of the background partially, allowing the image to show through.
OPTION 1 - USING STORYBOARDS
For those who have their view in a storyboard or .xib, you simply do it in interface builder by selecting the option "Clear Color" for the Background of the view in the Utilities Pane (the pane on the right). "Clear Color" will give the view a completely transparent background.
If you need a background color that is partially transparent, select the desired background color with the color picker and use the Opacity slider at the bottom to set the transparency.
OPTION 2 - USING COLOR ASSETS (AND STORYBOARDS)
Another very useful option is to add colors to your .xcassets library, so that you can use the same color easily in different views. You can make these colors (semi-)transparent as well, here's how:
Open your .xcassets library
Add a Color Set
Give it a useful name and select the color thumbnail
In the Attributes Inspector you can then change the color and use the slider to adjust its opacity
Go back to your storyboard and select the view you need this transparent background color
In the Background option of in the Attributes Inspector you can now select the Color you added to your .xcassets library. This is very useful if you have multiple views across your app using the same background.
In code you can access the colors from your Color Assets using:
SWIFT (UIColor): UIColor(named: "DP Textfield")
SWIFTUI (Color): Color("DP Textfield")
I think what you mean is you want the backgroundColor of your UIView to be semi transparent? If you want white/transparent use this:
myView.backgroundColor = [UIColor colorWithWhite:myWhiteFloat alpha:myAlphaFloat];
else if you want it to be another color use the general UIColor method: +colorWithRed:green:blue:alpha:
This will work.
myView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.7f];
Eventually you already have a color so you could use .colorWithAlphaComponent like this:
let exampleColor = UIColor.blackColor()
overlayView.backgroundColor = exampleColor.colorWithAlphaComponent(0.8)
For Swift 4+ :
Black translucent view:
view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
I believe you should use:
myView.alpha = myAlphaFloat;
myView.opaque = NO;
For Xamarin C#, at this time, the visual storyboard does not have the "opacity" slider of Xcode's storyboard mentioned by Bocaxica.
If you set BackgroundColor for View nameOfView in storyboard, then in your view controller's ViewDidLoad, add this line to set alpha:
nameOfView.BackgroundColor = nameOfView.BackgroundColor.ColorWithAlpha( 0.7f ); // A value between 0 and 1.
Swift 3+
white half transparent:
view.backgroundColor = UIColor(white: 1, alpha: 0.5)
or black half transparent:
view.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5)

Resources