Add subView behind items to UINavigationBar in iOS 11 - swift

In my UINavigationBar subclass I am adding a subView with insertSubview(customView, at: 0) in order to place it in the very 'back' of the UINavigationBar.
In iOS 10 the added subView will be added the Title and UIBarButtonItems as I want it, but in in iOS 11 it seems like Apple changed something because no matter what I try the customView will be placed every time in the front of the UINavigationBar.
//containerView
containerView.frame = CGRect(x: 0, y: -(statusBarHeight), width: UIScreen.main.bounds.width, height: frame.height + statusBarHeight)
containerView.clipsToBounds = true
insertSubview(containerView, at: 0)
I already tried changing the index.
Any idea how I should tackle that problem?

You can look at this. I solved it this way:
override func layoutSubviews() {
super.layoutSubviews()
for aView in self.subviews {
if NSStringFromClass(type(of: aView)) == "_UINavigationBarContentView" {
aView.frame = CGRect(x: 0, y: 20, width: aView.frame.width, height: aView.frame.height)
}
else if NSStringFromClass(type(of: aView)) == "_UIBarBackground" {
aView.frame = CGRect(x: 0, y: 0, width: aView.frame.width, height: self.frame.height)
}
}
}

Related

How to order views' layers on top of each others in Swift

I added the redView as a subView of the textField and used AutoLayout to constraint it to be as it appears in the image, but the problem here now is
I want to bring the red view to be on top of the border
I tried to use this method
bringSubviewToFront(floatingPlaceholderContainer)
but it didn't work, also tried to use the layer.zPosition = .greatestFiniteMagnitude and it also didn't work
Edit-
the code I used and didn't work as I expected
override func layoutSubviews() {
super.layoutSubviews()
self.redlayer.backgroundColor = UIColor.red.cgColor
self.redlayer.frame = CGRect(x: 10, y: -10, width: 100, height: 30)
self.layer.addSublayer(self.redlayer)
self.redlayer.zPosition = 10
}
and this is the result
You need to configure the timing of when you're adding this layer. This approach works fine for me:
class MyTextField : UITextField {
let redlayer = CALayer()
override func layoutSubviews() {
super.layoutSubviews()
self.redlayer.backgroundColor = UIColor.red.cgColor
self.redlayer.frame = CGRect(x: 10, y: -10, width: 100, height: 30)
self.layer.addSublayer(self.redlayer)
self.redlayer.zPosition = 10
}
}

Trying to change the frame of UIView in swift whilst the app is running?

I am trying to change the frame of a UIView when the orientation of my device is changed but nothing appears to work. Here is my code:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
guard
let portraitScreenView = viewScreenSizePortrait,
let overLay = overLayView else{return}
if UIDevice.current.orientation.isPortrait{
print("isPortrait")
overLay.frame = CGRect.init(x: 0, y: 0, width: portraitScreenView.width, height: portraitScreenView.height)
self.overLayView.frame = overLay.frame
}else{
print("isLandscape")
overLay.frame = CGRect.init(x: 0, y: 0, width: portraitScreenView.height, height: portraitScreenView.width)
self.overLayView.frame = overLay.frame
}
print("self.overLayView.frame: \(self.overLayView.frame)")
}
Add self.setNeedsDisplay() after your frame change.

Swift: NSStackView, bug only one subview is added

Hello in my code below I want to add NSImageView to my stackView, but there is a bug because there is only one that is added. The loop is 3 iterations so normally I should have 3 images:
let imageView = NSImageView(frame: NSRect(x: 0, y: 0, width: 50, height: 50))
imageView.image = image.image
icons.forEach { _ in
stackImage.addArrangedSubview(imageView)
}
print(stackImage.subviews.count) // Outpout 1
Create the NSImageView instances inside the forloop.
And you need to check stackImage.arrangedSubviews.count not stackImage.subviews.count
var icons = [NSImage(named: ""),NSImage(named: ""),NSImage(named: "")]
icons.forEach { image in
let imageView = NSImageView(frame: NSRect(x: 0, y: 0, width: 50, height: 50))
imageView.image = image
stackImage.addArrangedSubview(imageView)
}
print(stackImage.arrangedSubviews.count)

Resize image view in swift

I need to programaticaly move an image view based on some conditions in my app. I do this by using CGAFfineTransform. However, after I move my view and try to resize it to fill in the resulting gap, the view doesn't resize. What can I do differently?
override func viewDidLoad() {
super.viewDidLoad()
imageView.transform = CGAffineTransform(translationX: 0, y: 44)
imageView.frame = CGRect(x: 0, y: 0, width: imageView.frame.width,
height: imageView.frame.height + 44)

UIView sizing programmatically

I have an UIView with two containers in IB with two filter buttons (one is up and one is down). I have created two functions called filterUP and filterDOWN and they work like this :
#IBAction func FilterDown(sender: AnyObject) {
self.FilterDownButton.hidden = true
var duration = 0.5
self.FilterView.clipsToBounds = true
UIView.animateWithDuration(duration, animations: {
self.FilterView.frame = CGRect(x: 0, y: 65, width: 375, height: 195)
}, completion: { finished in
self.FilterUPButton.hidden = false
self.FilterDownButton.hidden = false
})
And what it does is animate the filter UIView up and down. which is fine and they work.
When the app starts I want the UIView (filter) at CGRect(x: 0, y: 65, width: 375, height: 65) - i.e. hidden only 20 high.
So I did
self.view.frame = CGRect(x:0, y:65, width: 375, height: 20)
in viewDidLoad.
This has not done anything and the UIView is still full size when the app runs.
I have toggled with AutoLayout (On/Off) and Size Classes (on/Off) and this does not work.
How can I get the UIView a certain size when the app starts up ?