I'm making an iOS app with XCode 6.1, targeted operation system version is iOS 7 and iOS 8. I wanna change the border color of a UITextField, since I'm not sure how to do this using interface builder, I simply added this line in the view controller:
self.input_username.layer.borderColor = [[UIColor redColor] CGColor];
It worked as expected when running the app with simulator, now I wonder if it is possible to show the effect in storyboard? Because for what I can tell, even when executing the app, the border color becomes red, it is still black(the default color) in interface builder... I don't want to run the app every time when I made a little change for visual effect by code...
Is this what you mean? You want storyboard change as your code settings? I have't seen this before, and I don't think that's possible. Since they are two ways to the same purpose.
I think you just can see the change in storyboard only when you draw custom view, and you can use the #IBDesignable in your custom view's declaration, such as #IBDesignable class CounterView: UIView {}. Then in your storyboard, you set a view's class name as "CounterView" and change code in the override func drawRect(rect: CGRect) {} in your custom view's class, you will see the view in storyboard also be changed.
Related
I have a xib. I have a view controller that loads the xib and adds it to its subview. The xib has the background color set from the xib file (from interface) to a CUSTOM COLOR SET from assets (created by me).
Everything works fine.
Now, inside my view controller, in viewDidLoad I want to override that background color with something else. The problem I found and it replicates 100% is that overriding doesn't do anything, unless I do it in viewDidAppear.
So to sum up...
custom color background set from xib... overriding in viewDidLoad not working, overriding in viewDidAppear working
Xcode default color background set from xib (any other color except from assets custom colors)... overriding in viewDidLoad WORKS...
Why in the first case I cannot override the color and in the second I can?
Is there a hidden feature that I'm missing here? You simply cannot override a view background color in viewDidLoad if the color set from xib is custom color, but if it's any other color... like white, red, black or w/e Xcode already has everything works as expected.
If it has any impact... this view controller I'm talking about gets pushed on the navigation stack. But I don't see how this can have any impact.
Reproduction Steps:
To replicate this... create a new sample project... that only has one view controller in it. Next add a custom color via assets -> new color set. Set the view controllers view background color from storyboard to the newly added color set. Then inside viewDidLoad change the background color of the view to something else... you will notice if you run the app it WON'T CHANGE if in storyboard there is a custom color set as background.
Somehow the background custom color set from storyboard overrides happen behind the scenes after viewDidLoad and before viewDidAppear.
I come late but have more info for future readers.
I just met this bug in my App for iOS 11 and iOS 12. The bug is solved by Apple since iOS 13.0.
So if you support previous version, you still need to apply the workaround from #AlanS, or not use custom colors in storyboard and xib :
func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
if #available(iOS 13.0, *) {
// Fix iOS 12 storyboard color bug.
} else {
view.backgroundColor = UIColor.black
}
}
Faced with this issue recently
I had xib file for table cell and custom colors in xcasset.
Colors are single appearance (dark mode not supported).
In cell swift class I have bool variable with didSet, where few outlets are modified: view.backgroundColor and label.textColor. Their values are based on variable value. There are ternar conditions so I was sure that color will be selected correctly.
On devices with iOS 12 (checked on 12.1 and 12.4 real and simulators) color didn't change at start but only after cell reuse.
After finding this question and few experiments, I have found that:
Setting custom color in xib file (no matter, if they have dark version or not) was performed after my didSet block and overrides my conditions results. And since I have set one of possible color in xib, I though that problem in data.
So I have reset outlets colors to default in xib and now it works
In case if you have to display some default color before some conditions, I guess putting it in init methods (awakeFromNib, viewDidLoad etc) should work
This bug was fixed in 13.0+
Duplicating answer from https://developer.apple.com/forums/thread/649009
One more strange workaround that helped me is to perform color updating code on the main thread.
It worked both in viewDidLoad and awakeFromNib.
DispatchQueue.main.async {
self.setupColors()
}
func setupColors() {
//your colors updating logic//
}
The app ran perfectly prior to updating to Xcode 8 Beta 6 and Swift 3. I've changed nothing else but now I have two problems.
First, a few random views are no longer showing up. They're just square, colored boxes. The views above them show up though.
In Interface Builder:
On simulator:
Second, my model VC is no longer appearing when segued. It did before and I can see the segue is being called but now its' not there.
If anyone can provide ideas about either problem it'd be greatly appreciated.
So between Xcode 7/Swift 2 --> Xcode 8/Swift 3, something changed with how to turn a UIView into a circle. Here is my code now:
func roundView (_ viewToRound: UIView) {
viewToRound.layer.cornerRadius = 20
//viewToRound.layer.cornerRadius = (viewToRound.frame.width/2)
viewToRound.clipsToBounds = true
}
As you can see, I've replaced my cornerRadius method to be an explicit "20" instead of inferred from the view size. With my previous "frame.width" the views were literally not showing up at all. Now they're back to normal. I don't know what changed but this definitely fixed it.
Something may have happened to the auto layout constraints. Double check that those are set properly.
Also, you don't need to use the simulator to verify this; use the Assistant editor's Preview view:
As a sanity check, the first thing I would do is reset all of the elements in your view to the suggested constraints to see if that resolves the problem.
It's definitely an AutoLayout issue in Xcode 8. The problem doesn't exist without using AutoLayout. I made this workaround using a protocol:
protocol Roundable {}
extension Roundable where Self: UIView{
func roundCorners(){
self.layer.cornerRadius = self.bounds.height / 2
}
}
class CustomView: UIView, Roundable {
override var bounds: CGRect {
didSet{
roundCorners()
}
}
}
Make the view involved a CustomView and it will show up rounded. I use a protocol here, because in this way it's easy to extend an already existing UIView subclass with the functionality to round the corners. Of course it is possible to set the cornerRadius directly in the bounds property observer.
There is an issue with iOS 10 UIView lifecycle & AutoLayout.
What I mean by that is that in methods such as viewDidLoad & viewWillAppear the frames on all UI elements are `{{0,0},{1000,1000}}.
In cases such as with setting round corners makes rounded corners with 500px & you get invisible UI components :)
How I resolved this issue is by setting the rounded corners in viewDidLayoutSubview in UIViewControllers or layoutSubviews in UIView subclasses.
I made a Cocoa Touch Class called BlackCircle, a UILabel subview which called the drawRect() method to make a black circular label. I dragged a UILabel onto the LaunchScreen.xib file, and when I assigned the Cocoa Touch Class File as the class of the UILabel, I got an error-
"Launch Screen may not use instances of BlackCircle".
It works fine on the main.storyboard file, but it doesn't work on the LaunchScreen.xib file. How can I fix this? Thanks!
LaunchScreen will not load your custom instances. Remember the app hasn't launched yet. Thus you cannot have custom instances.
You are only allowed to use basic UIKit classes like UIView, UIImageView, UILabel, etc.
Your best bet would be to make an image resource for the black circular label and import it to the LaunchScreen.xib
Yes there is a way!
You can add an image view and use SF image like "circle.fill" (just enter the name in the topmost text field) and use tint color to style it in your way.
Does anyone know of a comprehensive tutorial on implementation of PaintCode, using variables with it, and getting the view to update. I am struggling my way through it. I have built a custom class, and linked a view controller, with a UIView, and I can see the simple graph I made. I have linked it up so that it is #IBDesignable & #IBInspectable and both work fine. I am just not sure how to pass a variable through to the UIView.
I also have absolutely no idea how to get the thing to update when the variable changes.
Any assistance in this would be great, it has taken all day so far and I feel nowhere closer to solving the issue.
I do appreciate your time and effort.
There a many tutorials in PaintCode home page and at this other website, good lucky
However to access the values you create you just need to create an outlet from the UIView to your UIViewController class and class myViewName.myVariableName = myValue
As this step by step tutorial explain
The only tutorials I've found are the PaintCode website.
There are three things that I tend to adjust when trying to add/remove parameters to make my drawings more customizable via code.
When you click on a canvas, there is a drop down menu in the inspector that allows you to include a draw method, an image method, or both when you export the style kit.
When selecting the color in the color palette, there is a drop down menu in the upper right that allows you to make the color a parameter, so that when you export, you can set the color via code.
Add a frame to the canvas and set the constraints in the inspector. These constraints are the old style layout constraints that are very annoying, but doing this inserts a rect parameter in the exported methods which you can set in the code as well.
I don't know any other good PaintCode tutorials - over and above - the tutorials suggested. But after some research, I think I know the answer to your problem:
Background before the answer: I had the same problem. For example, you have a good sized image (created by PaintCode) that works on all iPhone device except the iPhone 4S.
To solve my issue:
Open PaintCode & find the “Frame” button.
Learn a new word “Parametric”. That is what we are dealing with. When the frame changes in size, you set whether the objects inside the frame change size or stay the same.
Watch the Dynamic Shapes tutorial on the PaintCode site. All of the answers are within this short youTube video. It took 5 times of watching it until I have extracted all of the information I needed to get it to work.
If you want the more details, keep reading:
#IBDesignable
class beerViewClass: UIView {
override func drawRect(rect: CGRect) {
SecurityStyleKit.drawCarDashboard(frame: self.bounds, wageIncome: "yo!")
}
}
Notice I can set the frame size as I have multiple views of the same image. Also I can send in variables to the drawCarDashboard.
Within PaintCode, put the objects you want to scale / shrink inside the frame.
Set the Springs and Struts for each item in the frame. For example, do you want it to shrink, stay vertically centered, etc.
Export your StyleKit to Xcode.
in Xcode, using Storyboard or code, add the UIViews to your View
Controller
Add a new Swift file.
Change the blank Swift file to a subclass of UIView & add code (see example)
In storyboard view, select the views that were added.
Set the view to the class you wrote (beerView)
I hope that helps. I hope my explanation was clear.
I am trying to set a background image for my main superview in the story board editor without creating another view(just for a background image). I can change the class of my main view to UIImageView, but the editor will not show me the option to specify a background image. How can I make this work?
It is possible, but you won't get visual feedback from the storyboard. Under the Identity inspector (cmd+option+3), there is a pane for setting user-defined runtime attributes, and setting the backgroundColor to a [UIColor colorWithPatternImage:] should work just fine. I would however, for clarity, keep that sort of stuff in the viewDidLoad-method