I have created a custom IBDesignable UISegmentedControl class.
The class has no build errors but has warnings, it does not update inside of Xcode. There are the warnings, see the screenshot below.
#IBDesignable open class UISegmentedControlBorderless : UISegmentedControl {
#IBInspectable var borderColor:UIColor = UIColor.white {
didSet {
setupUI()
}
}
#IBInspectable var textColor:UIColor = UIColor.white {
didSet {
setupUI()
}
}
#IBInspectable var textSelectedColor:UIColor = UIColor.red {
didSet {
setupUI()
}
}
required public init?(coder aDecoder:NSCoder) {
super.init(coder:aDecoder)
setupUI()
}
override init(frame:CGRect) {
super.init(frame:frame)
setupUI()
}
override open func awakeFromNib() {
super.awakeFromNib()
setupUI()
}
override open func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setupUI()
}
fileprivate func setupUI() {
tintColor = borderColor
let attributes = [NSAttributedStringKey.foregroundColor: textColor]
let attributes2 = [NSAttributedStringKey.foregroundColor: textSelectedColor]
setTitleTextAttributes(attributes, for: .normal)
setTitleTextAttributes(attributes2, for: .selected)
}
}
Warnings:
Unticking inherit module
Based on the first warning in your screenshot, Xcode is not finding your UISegementedControl subclass. This is commonly caused by not setting the correct module where the class is defined, and since your subclass is defined as open, it seems likely that you have it in a framework or module outside of the target app.
So, make sure where you set the custom class for the segmented control on the storyboard that you also selected the correct module for where the subclass is defined, and you probably want to uncheck "inherit module from target" in order to do so:
Related
In my code, I have created a custom button (i.e subclass of UIButton), But I am unable to set the font to the button. Have observed that, If I am using self.titleLabel?.text = title it works fine but whenever I am using method self.setTitle(title, for: .normal) font get reset to system font. I need that font for all the states of the button so I have to use the function setTitle. My custom button code is as follows
class RoundedButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
styleButton()
}
required public init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
styleButton()
}
func styleButton(title: String = "button", font: UIFont = .customFont16) {
self.setTitle(title, for: .normal)
self.backgroundColor = UIColor.yellow
titleLabel?.font = font
}
}
You can add a variable for setting font in a custom class. Then set the font from the viewController.
var titleFont: UIFont = UIFont.preferredFont(forTextStyle: .footnote) {
didSet {
titleLabel?.font = titleFont
}
}
Add the above code into your custom class and access it in the viewController like this.
#IBOutlet weak var roundButton: RoundedButton!
override func viewDidLoad() {
super.viewDidLoad()
roundButton.titleFont = .caption1
}
Now I'm practicing build IOS app without using storyboard , but I have a problem want to solve , I created a custom UIView called BannerView and added a background(UIView) and a title(UILabel) , and called this BannerView in the MainVC , but run this app , it crashes at the function setupSubviews() and I don't know why.
import UIKit
import SnapKit
class BannerView: UIView {
var background: UIView!
var title: UILabel!
override init(frame: CGRect) {
super.init(frame: frame)
setupSubviews()
}
convenience init() {
self.init(frame: CGRect.zero)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupSubviews()
}
func setupSubviews() {
background.backgroundColor = .gray
title.text = "INHEART"
self.addSubview(background)
self.addSubview(title)
}
override func layoutSubviews() {
background.snp.makeConstraints { make in
make.width.equalTo(ScreenWidth)
make.height.equalTo(BannerHeight)
make.left.top.right.equalTo(0)
}
title.snp.makeConstraints { make in
make.width.equalTo(100)
make.center.equalTo(background.snp.center)
}
}
}
class MainVC: UIViewController {
var bannerView:BannerView!
override func viewDidLoad() {
super.viewDidLoad()
bannerView = BannerView(frame: CGRect.zero)
view.addSubview(bannerView)
}
}
Your properties do not appear to be initialised
var background: UIView!
var title: UILabel!
You should initialize these in your init method
self.background = UIView()
self.title = UILabel()
If you use force unwrapping on a class property you must initialize in the init method. XCode should be complaining to you about this and your error message should show a similar error
You are not initialised the background view please initialised them
self.background = UIView()
self.title = UILabel()
and if you want to create custom view by use of xib the follow them Custum View
You must have to initialised the self.background = UIView() and self.title = UILabel() first.
You can initalised them in setupSubviews() function before the set/assign values to them.
I have a button that repeats throughout my app, so I created a subclass to avoid having to set all the basic properties every time.
I am able to set the background colour, the text colour, round the corners.
However, things fall apart when I try to set a default title - something other than "Button".
In Interface Builder it ignores the title, but it also then ignores the font colour, which works when I don't set the title.
If I run the app, it all looks fine, but one major point of using Interface Builder is to save the step of constantly running the app to check basic UI layout.
Here is the subclass.
Note that if you comment out the 2 setTitle lines, the button shows the correct text colour (white).
import UIKit
#IBDesignable class ContinueButton: UIButton {
#IBInspectable var titleColour: UIColor = .white {
didSet {
setTitleColor(titleColour, for: .normal)
}
}
#IBInspectable var bgColour: UIColor = UIColor.gray {
didSet {
backgroundColor = bgColour
}
}
#IBInspectable var buttonTitle: String = "Continue" {
didSet {
setTitle(buttonTitle, for: .normal)
}
}
override init(frame: CGRect) {
super.init(frame: frame)
setAttributes()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setAttributes()
}
public func setAttributes() {
setTitleColor(titleColour, for: .normal)
backgroundColor = bgColour
setTitle(buttonTitle, for: .normal)
}
override public func layoutSubviews() {
super.layoutSubviews()
setAttributes()
layer.cornerRadius = 0.5 * bounds.size.height
clipsToBounds = true
}
}
ps, My main objective is to create a reusable custom button that takes care of setting a bunch of defaults. If there's a better way to achieve that, I'd be very happy to hear that - especially if it could be done visually rather than through code.
Thanks for any advice you can give,
-Nico
Just override prepareForInterfaceBuilder() and add setAttributes().
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setAttributes()
}
The tintColor property will do the trick.
button.tintColor = UIColor.red
but to make sure to override the prepareForInterfaceBuilder()
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
button.tintColor = UIColor.red
}
I created a subclass of UIButton:
import UIKit
#IBDesignable
class CheckboxButton: UIButton {
#IBInspectable var checkboxBackgroundColor: UIColor = Project.Color.baseGray
#IBInspectable var textColor: UIColor = Project.Color.mainDarkText
#IBInspectable var checkboxHighlightedBackgroundColor: UIColor = Project.Color.main
#IBInspectable var highlightedTextColor: UIColor = Project.Color.mainBrightText
// MARK: - Properties
var isChecked: Bool = false {
didSet {
changeState()
}
}
// MARK: - Overrides
override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setupView()
}
override func beginTracking(_ touch: UITouch, with event: UIEvent?) -> Bool {
if isChecked {
isChecked = false
} else {
isChecked = true
}
return false
}
override func prepareForInterfaceBuilder() {
changeState()
}
// MARK: - #IBActions
// MARK: - Functions
private func setupView() {
isUserInteractionEnabled = true
changeState()
}
private func changeState() {
if isChecked {
backgroundColor = checkboxHighlightedBackgroundColor
self.setTitleColor(highlightedTextColor, for: .normal)
} else {
backgroundColor = checkboxBackgroundColor
self.setTitleColor(textColor, for: .normal)
}
}
}
Now I added a button inside the storyboard and gave it the class CheckboxButton. Everything works. Then I added an IBAction like this:
#IBAction func pointBtnTapped(_ sender: CheckboxButton) {
print("tapped")
selectButton(withNumber: sender.tag)
}
But this doesn't work (nothing prints out). It works with a normal button, but not if the button is the subclass CheckboxButton. Do you have any ideas?
Edit: screenshots
https://www.dropbox.com/s/ewicc349ag9l6y2/Screenshot%202016-10-06%2023.41.39.png?dl=0
https://www.dropbox.com/s/vxevzscueproivc/Screenshot%202016-10-06%2023.42.33.png?dl=0
(couldn't embed them here. Don't know why)
Thank you!
You broke UIButton by overriding beginTracking() and always returning false. This brainwashes the button into thinking it's never being clicked.
What was your intent there? In any case, return true there and your code will fire the #IBAction.
EDIT: You're overthinking the issue by using a low-level method meant for highly customized behavior such as non-rectangular buttons. You just need:
How to use UIButton as Toggle Button?
I'm new to swift and I'm just trying to create a subclass of uibutton. Except that I have this weird blue rounded rect appearing when the button is selected as shown below. When all I want is a nice white border.
The code of my class :
import UIKit
import QuartzCore
#IBDesignable
class ColorButton: UIButton {
//MARK: PROPERTIES
#IBInspectable var stickerColor: UIColor = UIColor.whiteColor() {
didSet {
configure()
}
}
override var selected: Bool {
willSet(newValue) {
super.selected = newValue;
if selected {
layer.borderWidth = 1.0
} else {
layer.borderWidth = 0.0
}
}
}
//MARK: Initializers
override init(frame : CGRect) {
super.init(frame : frame)
setup()
configure()
}
convenience init() {
self.init(frame:CGRectZero)
setup()
configure()
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
configure()
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
configure()
}
override func prepareForInterfaceBuilder() {
super.prepareForInterfaceBuilder()
setup()
configure()
}
func setup() {
//Border color
layer.borderColor = UIColor.whiteColor().CGColor
//Corner Radius
setUpCornerRadius()
}
func configure() {
backgroundColor = stickerColor
}
override func layoutSubviews() {
super.layoutSubviews()
setUpCornerRadius()
}
func setUpCornerRadius() {
layer.cornerRadius = CGRectGetWidth(bounds) * 0.205
}
}
I have checked your code. and I got same issue.
but If you set button type as Custom then this problem will not occur
Output :
Found something for buttonType :
You may find the discussion at CocoaBuilder's thread How to subclass UIButton? helpful, particularly Jack Nutting's suggestion to ignore the buttonType:
Note that this way the buttonType isn't explicitly set to anything,
which probably means that it's UIButtonTypeCustom. The Docs don't
seem to actually specify that, but since that's the 0 value in the
enum, that's likely what happens (and that seems to be the observable
behavior as well)
Source : https://stackoverflow.com/a/10278515/3202193