I am attempting to add a UIView without a nib file to the storyboard. I have dragged a UIView onto the storyboard and changed it's class to "Jahreskalender" with the Jahreskalender class as follows:
class Jahreskalender: UIView {
override func drawRect(rect: CGRect) {
// Drawing code
self.opaque = false
self.backgroundColor = UIColor(red: 100, green: 1, blue: 5, alpha: 0)
let jahresView = UIImageView(image: UIImage(named: "Calender.png"))
jahresView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
self.addSubview(jahresView)
}
}
When I run the app all I get is a black rectangle where I have dragged the UIView.
Do I need to load a XIB file or can I do everything with the "Jahreskalender" class programmaticall? Looked everywhere but can't find any tutorials.
Well, after some more trial and error I found my mistake. I need to call init(coder aDecoder: NSCoder).
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.opaque = false
}
Now it works. Thanks for the tips!
Related
I am trying to program a board games. There are multiple screens (game board, cards etc). At every screen I want the same status View at the buttom (to show how much money etc the player owns)
I created an UIView like this in a new file to use it globally:
let Resourcen=classResourcen()
class classResourcen: UIView {
init() {
super.init(frame: CGRect(x: 98, y: 1006, width: 739, height: 360))
let imageView = UIImageView(image: UIImage(named: "image"))
imageView.frame = CGRect(x: 0, y: 10, width: 739, height: 360)
self.addSubview(imageView)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
I use it in my my first storyboard screen:
self.view.addSubview(Resourcen)
If I add it to a 2nd storyboard sceen it works as well - but when I go back for my first page it disappears.
I read one cannot use an UIView multiple times. Now I wonder what I should do instead?
Make this view in another file or in .xib.
I'm learning to develop iOS apps in XCode.
I've created simple custom button (subclass of UIButton) that should have red background and green text. When running the app in iOS simulator, everything is ok. But in interface builder other colors (specified in interface builder) are used. Test project is available at https://www.dropbox.com/s/ro7i4omdbpwapi0/testapp%20%282%29.zip?dl=0. Can somebody help?
Here is source code of custom UIbutton class:
import UIKit
#IBDesignable class DefaultButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setup()
}
func setup() {
setTitleColor(UIColor.red, for: .normal)
backgroundColor = UIColor.green
//setBackgroundImage(UIImage.createGradient(colors: [ UIColor.defaultGradientStartColor, UIColor.defaultGradientEndColor ], startPoint: CGPoint(x: 0, y: 0), endPoint: CGPoint(x: 1, y: 0), size: CGSize(width: 200, height: 200)), for: .normal)
//layer.cornerRadius = 50
}
override func awakeFromNib() {
super.awakeFromNib()
setup()
}
}
The behaviour described in you answer is correct; but i think you mixes two different things.
Basically, if you want to tint your button title, and your button background, you have to use the fields availables in interface builder. You have some nice properties to set up these things easely.
Use interface builder's parameters to design your look
So, in this case, defining a titleColor and a backgroundColor in your view setup is not relevant, since it's hardcoded.
If instead, you want to display a custom look to your button - like rounded corner - in your storyboard, you could use the #IBInspectable keyword to add new properties in interface builder.
#IBDesignable
class DefaultButton: UIButton {
#IBInspectable var borderWidth: CGFloat = 0 {
didSet {
layer.borderWidth = borderWidth
}
}
#IBInspectable var borderColor: UIColor? {
didSet {
layer.borderColor = borderColor?.cgColor
}
}
#IBInspectable var cornerRadius: CGFloat = 0 {
didSet {
layer.cornerRadius = cornerRadius
layer.masksToBounds = cornerRadius > 0
}
}
// ...
}
By doing this, you can edit and see your view with a nice render in your storyboard!
Custom properties directly in storyboard
Sometimes I need to create same Views (or ImageViews) in Swift.
For example, make same size and image, delete the view, and make it again (and sometimes change the view's image or size).
In this case, of course writing same codes each time to need the view is not good.
So I want to find good way to create same views multiple times.
Now I use this code when I create same ImageView.
*CreateImage.swift
class aImageView: UIImageView {
override init(frame: CGRect) {
super.init(frame: frame)
let aImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 70, height: 50))
aImageView.image = UIImage(named: "item_a01_70x50")
aImageView.tag = 100
aImageView.isUserInteractionEnabled = true
aImageView.backgroundColor = UIColor.lightGray
self.addSubview(aImageView)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
}
class bImageView: UIImageView {
override init(frame: CGRect) {
super.init(frame: frame)
let bImageView = UIImageView(frame: CGRect(x: 0, y: 0, width: 70, height: 50))
bImageView.image = UIImage(named: "item_b02_70x50")
bImageView.tag = 200
bImageView.isUserInteractionEnabled = true
bImageView.backgroundColor = UIColor.lightGray
self.addSubview(bImageView)
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)!
}
}
*TopView.swift
class TopView: UIView {
var aview: aImageView!
var bview: bImageView!
init(frame: CGRect, stage:Int){
super.init(frame: frame)
aview = aImageView(frame :CGRect(x: 0, y: 0, width: 70, height: 50))
self.addSubview(aview)
bview = bImageView(frame :CGRect(x: 100, y: 100, width: 70, height: 50))
self.addSubview(bview)
//...and sometimes delete them, create them again other time, and create...
}
}
If you know better way, could you tell me?
Thanks.
i think you can make an extension of UIImageView like this:
extension UIImageView {
convenience init(_imageName: String = "",
_frameTulpe: (x: CGFloat, y: CGFloat, w: CGFloat, h: CGFloat) = (0, 0, 0, 0),
_tag: Int = 0,
_isUserInteractionEnabled: Bool = true,
_backgroundColor: UIColor = UIColor.lightGray)
{
self.init(image: UIImage(named: _imageName))
frame = CGRect(x: _frameTulpe.x, y: _frameTulpe.y, width: _frameTulpe.w, height: _frameTulpe.h)
tag = _tag
isUserInteractionEnabled = _isUserInteractionEnabled
backgroundColor = _backgroundColor
}
}
And then, in your TopView.swift will be:
class TopView: UIView {
var aview: aImageView!
var bview: bImageView!
init(frame: CGRect, stage:Int){
super.init(frame: frame)
aview = UIImageView(_imageName: "item_a01_70x50", _frameTulpe:(0, 0, 70, 50), _tag: 100)
self.addSubview(aview)
bview = UIImageView(_imageName: "item_b02_70x50", _frameTulpe:(100, 100, 70, 50), _tag: 200)
self.addSubview(bview)
//...and sometimes delete them, create them again other time, and create...
}
}
uh hun! You just need merge the aImageView class and bImageView class. Then the variable property can be set after that the object be created, or you can define the other init method with it is contain the different parameter that be used for initializing the variable property.
Define just one class(ex: Utility.swift) which will provide custom Views.
Last but not the least you need to autolayout after adding subview(ex: aImageView).
I am following this technique.
I am trying to build custom components in Swift 2.2, and obviously missing something essential. My views ignore the frame rect.
In the containing view, I add the view programmatically like this:
let arrowControl = ArrowControl(frame: CGRect(x: 100 , y: 100, width: 300, height: 300))
self.view.addSubview(arrowControl)
In fact, even if I programmatically add a UIView or UIControl, without subclassing it - then the view ignores the frame rect, and occupies the entire screen.
Here are the essential parts of my custom view:
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func layoutSubviews() {
super.layoutSubviews()
renderComponent(frame)
}
EDIT>>>>
If I change my example, and remove renderComponent, I still get the same problem.
override func layoutSubviews() {
super.layoutSubviews()
self.clipsToBounds = true
backgroundColor = UIColor.yellowColor()
// renderComponent(self.frame)
}
Or even doing the following ignores the frame rect, and gives me a full screen block of colour:
let test = UIView(frame: CGRect(x: 100 , y: 100, width: 300, height: 300))
test.backgroundColor = UIColor.redColor()
self.view.addSubview(test)
Doh! I worked it out. It turns out it was my own fault, as I'd implemented the following in the containing view:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
for view in self.view.subviews {
view.frame = UIScreen.mainScreen().bounds
}
}
I'm having trouble with transparency in drawRect. I have a custom UIView. If I draw a rect bezier path and fill it with gray the color will be solid without any transparency even though I have the alpha set to 0.6. :
import UIKit
class MyView: UIView {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override func drawRect(rect: CGRect) {
let grayOverlay = UIBezierPath(rect: rect)
UIColor(red: 34, green: 211, blue: 121, alpha: 0.6).set()
grayOverlay.fill()
}
}
Am I missing something here?
Views have and -opaque property.
By default is set to true due to performance reasons. If the view is not opaque it will require transparent blending, that is more intensive.
By setting to false you agree to have transparency between your view and what it is displayed under.