how to add custom view in a middle of base view - ios

I have created custom language view. I want that view show on a middle of center of iPad.
Here is what I have
static let langView = UINib(nibName: "LanguagesListView", bundle: nil).instantiate(withOwner: nil, options: nil)[0] as! LanguagesListView
func languagesPopup() -> Void {
BaseVC.langView.delegate = self
BaseVC.langView.frame = self.view.bounds
BaseVC.langView.center = CGPoint(x:self.view.frame.size.width / 2, y:
self.view.frame.size.height / 2);
self.view.addSubview(BaseVC.langView)
}
When I call this method it shows somewhere in the left.

You're setting the frame of your langView equals to bounds of your root view, so the position x, position y, width and height will be same of your root view. If the width of langView is same of parent view your view always will be in left side. Try set different size for your langView. Try something like this:
override func viewDidLoad() {
super.viewDidLoad()
let viewT = UIView()
viewT.frame.size = CGSize(width: 50, height: 50)
viewT.backgroundColor = UIColor.red
viewT.center = self.view.center
self.view.addSubview(viewT)
}

Related

Firebaseui on iOS: can't set background color on customized subclassed login screen

I'm subclassing the login screen of Firebaseui with:
import UIKit
import FirebaseUI
class LoginViewControllerCustom: FUIAuthPickerViewController {
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .red
let arr = Bundle.main.loadNibNamed("LoginText", owner: nil)!
let v = arr[0] as! UIView
self.view.addSubview(v)
}
}
My implementation works as I see the xib LoginText loaded on login screen.
But the background color is royally ignored.
How to enforce a bg color on the login screen from that subclass?
Edit: if I apply the answer below with view.insertSubview(imageViewBackground, at: 0)
Here is what I get:
As you can see the image gets inserted under the view that holds the login button. If I set "at: 1" it completely cover the buttons and they can't be used.
I resolved the problem in an unexpected way.
On the delegate method that would load this controller, I changed:
func authPickerViewController(forAuthUI authUI: FUIAuth) -> FUIAuthPickerViewController {
return LoginViewControllerCustom(authUI: authUI)
}
to
func authPickerViewController(forAuthUI authUI: FUIAuth) -> FUIAuthPickerViewController {
return LoginViewControllerCustom(nibName: nil, bundle: Bundle.main, authUI: authUI)
}
The addition of Bundle.main solved the issue, and replaced the original controller by mine, which was several levels deeper until that.
Not sure exactly why, but this did solve the issue.
you can try to put "fake" image background:
override func viewDidLoad() {
super.viewDidLoad()
let width = UIScreen.main.bounds.size.width
let height = UIScreen.main.bounds.size.height
let imageViewBackground = UIImageView(frame: CGRect(x: 0, y: 0, width:
width, height: height))
imageViewBackground.backgroundColor = .red
view.insertSubview(imageViewBackground, at: 0)
let arr = Bundle.main.loadNibNamed("LoginText", owner: nil)!
let v = arr[0] as! UIView
self.view.addSubview(v)
}
Edit: try this it's not elegant but it solves the problem.
override func viewDidLoad() {
let scrollView = view.subviews[0]
scrollView.backgroundColor = .clear
let contentView = scrollView.subviews[0]
contentView.backgroundColor = .red
let width = UIScreen.main.bounds.size.width
let height = UIScreen.main.bounds.size.height
let backgroundImage = UIImageView(frame: CGRect(x: 0, y: -1, width: width, height: height))
view.backgroundColor = .red
backgroundImage.contentMode = UIView.ContentMode.scaleAspectFill
view.insertSubview(backgroundImage, at: 0)
}

How to add multiple view controllers on scrollview without them overlapping

I'm trying to fit multiple view controllers on a scroll view. But the views overlap on the screen
let settingView: SettingsView = SettingsView(nibName: "SettingsView", bundle: nil)
self.addChild(settingView)
self.scrollView.addSubview(settingView.view)
settingView.didMove(toParent: self)
settingView.view.frame = self.view.bounds
let mainView: MainView = MainView(nibName: "MainView", bundle: nil)
self.addChild(mainView)
self.scrollView.addSubview(mainView.view)
mainView.didMove(toParent: self)
mainView.view.frame = self.view.bounds
var mainFrame: CGRect = mainView.view.frame
mainFrame.origin.x = settingView.view.frame.width
mainView.view.frame = mainFrame
let connectionView: ConnectionView = ConnectionView(nibName: "ConnectionView", bundle: nil)
self.addChild(connectionView)
self.scrollView.addSubview(connectionView.view)
connectionView.didMove(toParent: self)
connectionView.view.frame = scrollView.bounds
var connectionFrame: CGRect = connectionView.view.frame
connectionFrame.origin.x = 2 * self.view.frame.width
connectionView.view.frame = connectionFrame
self.scrollView.contentSize = CGSize(width: (self.scrollView.frame.size.width) * 3
, height: self.scrollView.frame.size.height)
self.scrollView.contentOffset = CGPoint(x: (self.view.frame.width), y: self.view.frame.height)
each view controller should fit the size of the screen but they overlap onto each other screen

only last added view is visible in UIScrollView iOS

I am facing an issue with scrollView. I have added scrollView in my storyboard as
View
- MainView
- ScrollView
- accountSavingSubView
Now I am trying to add views in accountSavingSubView as below
//MARK:- Create and add wallets on the UI
private func createAndAddWallets()
{
var yPosition : CGFloat = 0.0
//1. Create left hand side wallets with help of keys
for key in dictData.keys
{
let walletView:Wallet = Bundle.main.loadNibNamed("Wallet", owner: self, options: nil)?.first as! Wallet
walletView.translatesAutoresizingMaskIntoConstraints = false
walletView.frame = CGRect(x: 0.0, y: yPosition, width: accountSavingSubView.frame.width, height: accountSavingSubView.frame.height)
walletView.accountNameLabel.text = key
accountSavingSubView.addSubview(walletView)
yPosition += walletView.frame.maxY
walletView.isUserInteractionEnabled = true
print("walletView frame is :\(walletView.frame)")
}
//set continer scroll content size
self.contanerScrollView.contentSize = CGSize(width: self.accountSavingSubView.frame.width, height: CGFloat(80.0/320.0)*UIScreen.main.bounds.width*CGFloat(self.dictData.keys.count))
}
Where dictData is a dictionary of ([String: String]).
But in my view, I can see only last view is added on (x=0, y=0). ScrollView content size is correct & I can scroll without having views except last one at first place(x:0,y:0).
Please let me know what am I doing wrong here in my code while adding views.
You need to comment this
walletView.translatesAutoresizingMaskIntoConstraints = false
as it's used with setting constraints only ,and verify that the supplied frame values here are not 0
walletView.frame = CGRect(x: 0.0, y: yPosition, width: accountSavingSubView.frame.width, height: accountSavingSubView.frame.height)
btw you can also comment it as the frame will be captured as you set it in xib if you make it freedom size

childViewController.view.frame in UIView present different value

I use childViewController to separate view in project, but some strange issue happened, here is my code.
class ViewController: UIViewController {
var container = UIView()
var childVC = ChildViewController()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
addChildViewController(childVC)
childVC.didMove(toParentViewController: self)
addChildView()
setContainerFrame()
}
func setContainerFrame() {
container.frame = CGRect(x: 0, y: 100, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height - 100)
container.backgroundColor = .red
view.addSubview(container)
}
func addChildView() {
let frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
childVC.view.frame = frame
childVC.view.backgroundColor = .green
container.addSubview(childVC.view)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
print("childVC.view.frame: \(childVC.view.frame)")
}
}
class ChildViewController: UIViewController {
}
when I exchange the order invoking func addChildView() and func setContainerFrame() in ViewController's viewDidLoad(), xcode'console prints different frame log.
This is due to the autoresizingMask of the childVC.view. By default this is set to have flexible width and height. So if you set the frame of the container and then the frame of the childVC.view then you get the actual value you set but if you reverse it and set the frame of the childVC.view and then the container the frame of the childVC.view is automatically updated to have the same relative width and height.
For example if the frame size for the container was 100 x 100 and then you change it to 200 x 200 the frame size for childVC.view will be doubled.
To remove this set the childVC.view.autoresizingMask = [] so it remains as you set it.
The strange behavior occurs because in addChildView() function you are adding the child view controller's view as subview to container view but container view's frame is setting in the function setContainerFrame() which is not yet called. That means you are adding a subview to a view whose frame hasn't set already.

Swift. Flip animation. FromView is not displayed

I've wrote this code to create a simple flip animation:
func frontView (view:UIView) ->UIView {
var frontView: UIView
frontView = UIView()
frontView.frame = view.frame
frontView.center = CGPoint(x: 0, y: 0)
return frontView
}
func backView (view:UIView) ->UIView {
var backView: UIView
backView = UIView()
backView.frame = view.frame
backView.backgroundColor = UIColor.redColor()
backView.center = CGPoint(x: view.frame.width/2, y: 0)
view.addSubview(backView)
return backView
}
func flipViewAnimation (viewToAnimate: UIView) {
var animationOption = self.animationOption
var duration = self.duration
UIView.transitionFromView(backView(viewToAnimate), toView: frontView(viewToAnimate), duration: duration, options: animationOption, completion: nil)
//
}
As a viewToAnimate I use views with labels and imageViews inside, which I've created in AutoLayout. The result I'm trying to achieve more or less should look like this. First I see views filled with color, then they flip and show the content inside (labels and ImageViews).
But it works in a different way. Views appear already with content (labels and ImageViews) then just flip and again show the same content.
I've created each view programmatically and it works very well for me now.

Resources