Swift 4 Ios same UIView at multiple screens - ios

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.

Related

UITextField subclass with bar underneath: bar not going all the way

The objective
I've made my own UITextField subclass, to design it in such a way that there is no border, only a white line under the text. (Subclass code below)
The issue
Unfortunately, the white line does not go to the end of the text field (in terms of width):
I've constrained the text field to have 0 px distance to both the left and right edges of the view, but as the images below show, the line does not meet those constraints.
My investigation and hypotheses
I've put in quite some time to debug, the only thing I can think of is that the dimensions specified in the code (copied below) are exécute before the constraints are applied to the view, which is not something I know how to resolve.
The code
//In a UITextField subclass
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
public override func awakeFromNib() {
super.awakeFromNib()
setup()
}
func setup() {
self.delegate = self
// BORDER
// Remove rectangular border
self.borderStyle = .none
self.layer.borderColor = UIColor(red: 1, green: 1, blue: 1, alpha: 0).cgColor //Make transparent
self.layer.borderWidth = 0 // width = 0
// Add bottom border
bottomBorder = UIView(frame: CGRect(x: 0, y: self.frame.height, width: self.frame.width, height: 1))
bottomBorder.backgroundColor = UIColor.white
self.addSubview(bottomBorder)
}
the only thing I can think of is that the dimensions specified in the code (copied below) are exécute before the constraints are applied to the view,
Perfectly correct! The whole problem is that you are hard-coding the frame of the bar based on the frame of the text field. But the frame of the text field is not yet known during init.
Your entire approach here is wrong. You should be using autolayout constraints to constrain the bar to the text field, not giving the bar a fixed frame. That way, no matter what happens to the size of the text field (as it obeys the constraints you have given it), the size of the bar will follow along in perfect harmony.
You need
override func layoutSubviews() {
super.layoutSubviews()
bottomBorder.frame = CGRect(x: 0, y: self.frame.height - 1, width: self.frame.width, height: 1)
}
As correct frame size of superView is captured inside layoutSubviews not in init / awakeFromNib where the frame is set for current development device dimensions if it's in IB

How to Increase Navigation Bar Height

1. How can I increase the hight of my navigation bar just like Apple did for the iMessage app:
2. How do they make the navigation bar expand when the titleView is clicked to look like this:
I've tried creating a larger titleView, but it just gets clipped to the bounds of the default navigation bar height. How are they able to achieve this? Also, my view controllers are embedded in a navigation controller programmatically.
Unsure if you've just embedded Navigation into the app... or set this up programatically.
You'll need to add your navBar as a sort of "IBOulet", and then modify it's height based on an function/action/etc.
Say when you click "name button"; then something akin to "mainNavBar.heightAnchor.constant = 400" (where 400 is the new height).
Or if you've set this up manually, and have a auto layout constraint on the height of your nav bar, then you could set that up as a IBOutlet; and access it easier.
It would help if you posted some of your code, or atleast how you've set this up.
Use this class for navigation bar height :
import Foundation
import UIKit
class NavigationBar: UINavigationBar {
//set NavigationBar's height
//For iphonex, I recommended to set the minimum height to 88 or higher.
var customHeight : CGFloat = 100
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
translatesAutoresizingMaskIntoConstraints = false
}
override func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width, height: customHeight)
}
override func layoutSubviews() {
super.layoutSubviews()
self.tintColor = .black
frame = CGRect(x: frame.origin.x, y: 0, width: frame.size.width, height: customHeight)
// title position (statusbar height / 2)
setTitleVerticalPositionAdjustment(-10, for: UIBarMetrics.default)
for subview in self.subviews {
var stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("BarBackground") {
subview.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: customHeight)
subview.backgroundColor = .yellow
}
stringFromClass = NSStringFromClass(subview.classForCoder)
if stringFromClass.contains("BarContent") {
subview.frame = CGRect(x: subview.frame.origin.x, y: 20, width: subview.frame.width, height: customHeight - 20)
}
}
}
}
Use navigation view instead of navigation bar or use custom view on viewDidLoad function hide navigation bar and show your custom view

Custom view - a subclass of uiview cannot be resized

It must be a simple thing but I couldn't find a clue,
I am having a imageview and trying a scribbling view which is a subclass of UIview on top of it to allow scribbling. All works fine except for resizing the scribbling view, it occupies the whole screen all the time I couldn't make it smaller.
class ScribbleView: UIView
{
let backgroundLayer1 = CAShapeLayer()
required init()
{
// super.init(frame: CGRect.zero)
super.init(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
layer.addSublayer(backgroundLayer1)
layer.masksToBounds = true
}
class HermiteScribbleView: ScribbleView, Scribblable
{
required init() {
print ("calling parent")
super.init()
}
}
/** main code **/
let hermiteScribbleView = HermiteScribbleView()
hermiteScribbleView.backgroundColor = .red
// imgView.autoresizesSubviews = true
// hermiteScribbleView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
//once this is done, hermieScribbleView is always stretched to full width and height no matter what I try
imgView.addSubview(hermiteScribbleView)
What i guess from above information is that, you might be using the frame of UIImageView to set the frame of UIView. you need to set the size of UIView same as the size of UIImage.
imgImageView.image.size
and secondly set the centre of UIView same as centre of UIImageView.
Hope this will work.

UIView / UIControl ignoring frame rect. Always fullscreen

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
}
}

Add UIView to Storyboard without a XIB file

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!

Resources