Swift - freezing when UITextField is IBDesignable with UIColor.init AND isSecureText - swift

I have a UITextField whose class is myCustomTextField. When myCustomTextField sets the textColor of the text field with UIColor.init and sets isSecureText to true, the app freezes after I type some text in the UITextField and then click off of the textfield.
The app does not crash and there is no error – the app just freezes and the only way to exit is to kill the app.
If I only set the textColor or only set isSecureText to true, the app does not freeze.
myCustomTextField:
#IBDesignable class myCustomTextField: UITextField {
override func layoutSubviews() {
super.layoutSubviews()
updateSomeStuff()
}
#IBInspectable var Style : Int = 0 {
didSet {
updateSomeStuff()
}
}
// set textColor and isSecureTextEntry
func updateSomeStuff() {
if Style == 0 {
textColor = UIColor.init(red: 122/255, green: 53/255, blue: 74/255, alpha: 1)
// self.textColor = UIColor.init(red: 122/255, green: 53/255, blue: 74/255, alpha: 1) // alternative attempt
isSecureTextEntry = true
// self.isSecureTextEntry = true // alternative attempt
}
}
}
The app does not freeze when I set the text color without calling init, but I am not sure how to resolve the issue since I need to set a specific text color.
Changed:
textColor = UIColor.init(red: 122/255, green: 53/255, blue: 74/255, alpha: 1)
To:
textColor = UIColor.red
Does anyone have ideas as to why setting the textColor with UIColor.init and setting isSecureText to true causes the app to freeze after typing and then clicking outside of the UITextField?

Related

Swift : change style of a button when pressed and reset other buttons

So I've got these buttons (3 stacks of 6, so 18), and what I want to achieve is when I press one of these buttons :
border color & text color changes
the other buttons are reset to their normal styling
But I don't want to disable the others via a "isEnabled" trick (I've only found solutions here involving isEnabled), I still want them to be enabled, I just want them not to be "highlighted" with my custom styling when one is pressed.
for the first part which is just the styling I did this inside the IBAction :
#IBAction func preset1Pressed(_ sender: UIButton) {
preset1.layer.borderColor = #colorLiteral(red: 0.4095217415, green: 0.6107917746, blue: 0.2774988226, alpha: 1)
preset1.layer.borderWidth = 0.42
preset1.setTitleColor(#colorLiteral(red: 0.4095217415, green: 0.6107917746, blue: 0.2774988226, alpha: 1), for: .normal)
}
This small portion was just for 1 button, but I guess if I have 18 of them I should make a class or a struct rather than copy this inside each IBAction ?? Or a func ?
Then for the 2nd part I'm not sure about how to do it, reversing to the original properties (set in the Attributes Inspector) of the other buttons when one is pressed.
Intuitively I'm sure it's a combination of an array of all the 18 buttons inside a function that would loop through all the array, and maybe make a bool on each button to check if they are pressed or not, but I really don't know how the syntax would be...
Worth noting also that if I press twice on the same button I don't want it to reverse to its original properties but to keep the "pressed" styling.
Thanks in advance !
Define UIButton array and add buttons when you add it to stack.set index as button tag (0-17)
fileprivate var btnArray:[UIButton] = []
btn0.tag = 0
btnArray.appent(btn0)
Then you can change style in button click function like this
#IBAction func preset1Pressed(_ sender: UIButton) {
btnArray.forEach { (button) in
if button.tag == sender.tag {
preset1.layer.borderColor = #colorLiteral(red: 0.4095217415, green: 0.6107917746, blue: 0.2774988226, alpha: 1)
preset1.layer.borderWidth = 0.42
preset1.setTitleColor(#colorLiteral(red: 0.4095217415, green: 0.6107917746, blue: 0.2774988226, alpha: 1), for: .normal)
view.layoutIfNeeded()
}else{
//add default style
view.layoutIfNeeded()
}
}
}
Don't frogot to add view.layoutIfNeeded() after this
So what suggested Dilan did not completely solve it on its own, though I experimented with it and it actually helped me solve it, apart I did these modifications :
I created my Array of buttons (called presetsArray) and tagged them.
Then I created a function to be called in all IBActions, but as sender.tag wouldn't work here's how I worked out the function :
func styleButtons(tag: Int) {
let tag = tag
presetsArray.forEach{ (button) in
if button.tag == tag {
button.layer.borderColor = #colorLiteral(red: 0.4095217415, green: 0.6107917746, blue: 0.2774988226, alpha: 1)
button.layer.borderWidth = 0.42
button.setTitleColor(#colorLiteral(red: 0.4095217415, green: 0.6107917746, blue: 0.2774988226, alpha: 1), for: .normal)
view.layoutIfNeeded()
} else {
button.layer.borderColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
button.setTitleColor(#colorLiteral(red: 0.4978774786, green: 0.5020093918, blue: 0.5019439459, alpha: 1), for: .normal)
}
}
}
Then in each IBAction for preset X I would call it like this :
styleButtons(tag: presetX.tag)
In the else section of my function as view.layoutIfNeeded() wouldn't reverse back to my original styling I just went for the color picker and picked my original styling, not the most legit way to do this I feel but it works !
Thanks a lot Dilan for the help.

How to make NSView transparent [duplicate]

I want to create an osx/cocoa application on my mac, which does something very simple: Display a text string on my mac, with no background. Ultimately this will be a timer which displays as an overlay on top of other windows, without being too intrusive.
I tried setting window.backgroundColor = NSColor(red: 1.0, green:0.5, blue:0.5, alpha: 0.5) (see the alpha is 0.5), in applicationDidFinishLaunching but this doesn't turn it into something remotely transparent.
Any good soul wants to suggest a way to do this?
NSWindow has a property 'opaque' which it is true by default.
The value of this property is true when the window is opaque;
otherwise, false.
Just change it to false:
override func viewWillAppear() {
super.viewWillAppear()
view.window?.opaque = false
view.window?.backgroundColor = NSColor(red: 1, green: 0.5, blue: 0.5, alpha: 0.5)
}
Swift 4 update: opaque has been renamed isOpaque
override func viewWillAppear() {
super.viewWillAppear()
view.window?.isOpaque = false
view.window?.backgroundColor = NSColor(red: 1, green: 0.5, blue: 0.5, alpha: 0.5)
}
Make the window non-opaque, and give it a clear background:
func applicationDidFinishLaunching(aNotification: NSNotification) {
window.opaque = false
window.backgroundColor = NSColor.clearColor()
}
A little update for Swift 3
A window subclass example with comment:
class customWindow: NSWindow {
override init(contentRect: NSRect, styleMask style: NSWindowStyleMask, backing bufferingType: NSBackingStoreType, defer flag: Bool) {
super.init(contentRect: contentRect, styleMask: style, backing: bufferingType, defer: flag)
// Set the opaque value off,remove shadows and fill the window with clear (transparent)
self.isOpaque = false
self.hasShadow = false
self.backgroundColor = NSColor.clear
// Change the title bar appereance
self.title = "My Custom Title"
//self.titleVisibility = .hidden
self.titlebarAppearsTransparent = true
}
More on Title Bar appereance here Title Bar and Toolbar Showcase
Swift 3/4
self.window?.isOpaque = false
self.window?.hasShadow = false
self.window?.backgroundColor = NSColor.clear
self.window?.titlebarAppearsTransparent = true

Issues creating toggle button

I am trying to create a button that reads "Special 1" then when it is clicked, the button reads "USED" and it stays as "USED" and doesn't allow the reader to toggle it back.
For example, the Twitter "follow" button can be pressed and then the button is changed to "following". However on Twitter, the user can click the "following" button and it will change back to "follow".
For my app, I want the user to be able to click "Special 1" and then the button is changed to "USED" and it remains that way forever.
Below is the attached code that I have created so far. The problem with my code so far is that the button doesn't read "Special 1" or "USED" when it is selected, the only thing it contains is the colors. The colors change how I want them to, but I can't get the words to appear and change.
import UIKit
class SpecialOneBTN: UIButton {
var isOn = false
override init(frame: CGRect) {
super.init(frame: frame)
initButton()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
initButton()
}
func initButton() {
layer.borderWidth = 2.0
layer.cornerRadius = frame.size.height/2
setTitleColor(UIColor(red: 255.0/255.0, green: 193.0/255.0, blue: 95.0/255.0, alpha: 1.0), for: .normal)
addTarget(self, action: #selector(SpecialOneBTN.buttonPressed), for: .touchUpInside )
}
#objc func buttonPressed() {
activateButton(bool: !isOn)
}
func activateButton(bool: Bool) {
isOn = bool
let color = bool ? UIColor(red: 102.0/255.0, green: 102.0/255.0, blue: 100.0/255.0, alpha: 1.0) : UIColor(red: 255.0/255.0, green: 193.0/255.0, blue: 95.0/255.0, alpha: 1.0)
let titleColor = bool ? UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0) : UIColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
let title = bool ? "USED" : "Special 1"
setTitle(title, for: .normal)
setTitleColor(titleColor, for: .normal)
backgroundColor = color
}
}

How to customize tintColor and resize UITabBarItem

The issues that I would like to change "Tintcolor" for each tabs. But the below code doesn't work at all.
And I added the button image and want to resize it using "UIEdgeInsetsMake". But the button is resized weirdly whenever I touched the button. I don't know why.
And I am using Swift 3.
class MainView: UITabBarController {
var TabFirst = UITabBarItem()
var TabSecond = UITabBarItem()
var TabThird = UITabBarItem()
var TabForth = UITabBarItem()
var TabFifth = UITabBarItem()
override func viewDidLoad() {
super.viewDidLoad()
tabBar.barTintColor = UIColor.white
TabFirst = self.tabBar.items![0]
TabFirst.image = UIImage(named: "btn_1-1")!//.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
TabFirst.imageInsets = UIEdgeInsetsMake(12, 10, 11, 11)
tabBar.items?[0].title = "length"
TabSecond = self.tabBar.items![1]
TabSecond.image = UIImage(named: "btn_2-1")!//.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
tabBar.items?[1].title = "length"
TabThird = self.tabBar.items![2]
TabThird.image = UIImage(named: "btn_3-1")!//.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
tabBar.items?[2].title = "length"
TabForth = self.tabBar.items![3]
TabForth.image = UIImage(named: "btn_4-1")!//.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
tabBar.items?[3].title = "length"
TabFifth = self.tabBar.items![4]
TabFifth.image = UIImage(named: "btn_5-1")!//.withRenderingMode(UIImageRenderingMode.alwaysOriginal)
tabBar.items?[4].title = "length"
}
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
switch item.tag{
case 0:
print("FirstTab")
UITabBar.appearance().tintColor = UIColor(red: 255/255.0, green: 67/255.0, blue: 99/255.0, alpha: 1.0)
case 1:
print("SecondTab")
UITabBar.appearance().tintColor = UIColor(red: 237/255.0, green: 193/255.0, blue: 53/255.0, alpha: 1.0)
case 2:
print("ThirdTab")
UITabBar.appearance().tintColor = UIColor(red: 70/255.0, green: 183/255.0, blue: 128/255.0, alpha: 1.0)
case 3:
print("ForthTab")
UITabBar.appearance().tintColor = UIColor(red: 12/255.0, green: 195/255.0, blue: 199/255.0, alpha: 1.0)
case 4:
print("FifthTab")
UITabBar.appearance().tintColor = UIColor(red: 105/255.0, green: 72/255.0, blue: 170/255.0, alpha: 1.0)
default:
break
}
}
override func viewWillAppear(_ animated: Bool) {
UIApplication.shared.isStatusBarHidden = false
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
EDIT:
You are missing breaks in your switch statement:
switch item.tag{
Also, you are doing a switch on the tag and I don't see anywhere you have tagged them accordingly in your code. You should get the index of the item instead.
I am not a Swift coder, this is how you do it in Objective-C to give you a hint:
NSInteger indexOfTab = [[self.tabBar items] indexOfObject:item];
Then you do your switch statement of indexOfTab.
Here is the Swift version.:
override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
print("the selected index is : \(tabBar.items.index(of: item))")
}
If you want to individually change the "tintColor" , you should set a custom selectedImage instead.
Beware:
By default, unselected and selected images are automatically created
from the alpha values in the source images. To prevent system
coloring, provide images with alwaysOriginal.
As far as the documentation goes, there are no "tintColor" property for a UITabBarItem.
However, the UITabBar itself has a tintColor property. But this is not setting anything individually.
Tint Color
You can specify a custom tint color for the bar background using the
Tint (barTintColor) field. The default background tint color is white.
Use the Image Tint (selectedImageTintColor) field to specify the bar
item’s tint color when that tab is selected. By default, that color is
blue.
Regarding your resize methods, you should resize your original image instead, or check this question if it does fit your needs. However, the UITabBar and UITabBarItem customizations are limited to what you can read in the documentations.
If you want to further customize things individually, I suggest you search for or create a custom solution instead.

Set UIColor in storyboard from variable/constant [duplicate]

This question already has answers here:
How to change dynamically color used in UIStoryboard
(2 answers)
Closed 4 years ago.
How do I set, let's say a text color on a UILabel, to a color defined in one of my classes like:
func mainAppColor() -> UIColor {
return UIColor(red: 0.2, green: 0.3, blue: 0.4, alpha: 1)
}
or
let mainAppColor = UIColor(red: 0.2, green: 0.3, blue: 0.4, alpha: 1)
in storyboard.
If your method is declared in some other class like:
class TextColorClass {
func mainAppColor() -> UIColor {
return UIColor(red: 0.2, green: 0.3, blue: 0.4, alpha: 1)
}
}
Then you can use it by make instance of that class this way:
let classInstance = TextColorClass()
yourLBL.textColor = classInstance.mainAppColor()
If it is declared like:
class TextColorClass {
let mainAppColor = UIColor(red: 0.2, green: 0.3, blue: 0.4, alpha: 1)
}
Then you can use it like:
let classInstance = TextColorClass()
yourLBL.textColor = classInstance.mainAppColor
If that method is declare in same class suppose in ViewController class then you can use it this way:
override func viewDidLoad() {
super.viewDidLoad()
yourLBL.textColor = mainAppColor()
}
func mainAppColor() -> UIColor {
return UIColor(red: 0.2, green: 0.3, blue: 0.4, alpha: 1)
}
UPDATE:
If you want to set any property from storyboard you can use #IBInspectable as shown in below example code:
import UIKit
#IBDesignable
class PushButtonView: UIButton {
#IBInspectable var fillColor: UIColor = UIColor.greenColor()
#IBInspectable var isAddButton: Bool = true
override func drawRect(rect: CGRect) {
}
}
And assign this class to your button.like shown into below Image:
And if you go to the Attribute Inspector you can see custom property for that button.
Now you can set it as per your need.
For more Info refer this tutorial:
http://www.raywenderlich.com/90690/modern-core-graphics-with-swift-part-1