Activity indicator is not in centered in TableView - ios

I want show activity indicator in TableView with NIB/XIB file, but it shown is not in center, it placed in right side
I do:
override func viewDidLoad() {
super.viewDidLoad()
let actInd: UIActivityIndicatorView = UIActivityIndicatorView()
actInd.frame = CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0)
actInd.center = self.view.center
actInd.hidesWhenStopped = true
actInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
self.view.addSubview(actInd)
actInd.startAnimating()
}

This approach works for me.
if let window = UIApplication.shared.keyWindow {
activityIndicator.frame = CGRect(x: window.frame.width/2, y: window.frame.height/2, width: 0, height: 0)
activityIndicator.hidesWhenStopped = true
activityIndicator.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.white
window.addSubview(activityIndicator)
}
Hope it helps :)

let actInd: UIActivityIndicatorView = UIActivityIndicatorView()
override func viewDidLoad() {
super.viewDidLoad()
actInd.frame = CGRect(x: 0.0, y: 0.0, width: 40.0, height: 40.0)
actInd.hidesWhenStopped = true
actInd.activityIndicatorViewStyle = UIActivityIndicatorViewStyle.whiteLarge
self.view.addSubview(actInd)
actInd.startAnimating()
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
actInd.center = self.view.center
}
/* Following two functions are acceptable also.
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
actInd.center = self.view.center
}
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
actInd.center = self.view.center
}
*/

You could:
add the UIActivityIndicator in your XIB/Storyboard
set it to hidden (in Storyboard)
create an IBOutlet
toggle spinner.isHidden when ever you want to show/hide it.

Related

Bottom border for text field doesn’t appear

I tried to add a bottom border to my text field but it doesn't work. I know that there are similar questions out there but none of those answers help. Also, I removed this line of code below and tried because there is no border by default, it still doesn't work:
username.borderStyle = UITextField.BorderStyle.none
Here is the whole code:
class SignUpScreen: UIViewController {
let username = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(username)
// Background color
view.backgroundColor = .white
username.placeholder = "Name"
username.borderStyle = UITextField.BorderStyle.none
let bottomLine = CALayer()
bottomLine.frame = CGRect(x: 0, y: view.frame.height - 1, width: view.frame.width, height: 1.0)
bottomLine.backgroundColor = UIColor.black.cgColor
username.layer.addSublayer(bottomLine)
username.translatesAutoresizingMaskIntoConstraints = false
username.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
username.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
username.widthAnchor.constraint(equalToConstant: 150).isActive = true
username.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
}
Hope someone can help me out! Thanks! :)
Here is what you were missing: You were using the main view's frame for creating the frame of your layer. You must use the text field.
Also first draw your text field properly with constraints then add layer to text field.
In viewDidLoad your content view is loaded to main memory. There is no frame assignment in that method. So use viewWillAppear or viewDidAppear.
Now when your view will appear every time a new TextField & a layer will be added. So you need to make a check to restrict that behaviour. E.g if a text field is already added to your view then don't add.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
view.addSubview(username)
/*
* Create the text field
*/
view.backgroundColor = .white
username.placeholder = "Name"
username.borderStyle = UITextField.BorderStyle.none
username.translatesAutoresizingMaskIntoConstraints = false
username.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
username.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
username.widthAnchor.constraint(equalToConstant: 300).isActive = true
username.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
/*
* Here add the shap layer
*/
let bottomLine = CALayer()
/*
* Here is what you were missing.
* You were using the main view's frame instead of your textfield
*/
bottomLine.frame = CGRect(x: 0, y: username.bounds.height - 1, width: username.bounds.width, height: 1.0)
bottomLine.backgroundColor = UIColor.black.cgColor
username.layer.addSublayer(bottomLine)
}
bottomLine.frame = CGRect(x: 0, y: view.frame.height - 1, width: view.frame.width, height: 1.0)
you must use username.bounds, instead of view.frame
let border = CALayer()
let width = CGFloat(3.0)
border.borderColor = UIColor.black.cgColor
border.frame = CGRect(x: 0, y: textFieldOutlet.frame.size.height - width, width: textFieldOutlet.frame.size.width, height: textFieldOutlet.frame.size.height)
border.borderWidth = width
textFieldOutlet.layer.addSublayer(border)
textFieldOutlet.layer.masksToBounds = true
rather than adding a layer maybe you should add your border as UIView and bring it to top also set your textField bgColor as clearColor:
class SignUpScreen: UIViewController {
let username = UITextField()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(username)
// Background color
view.backgroundColor = .white
username.placeholder = "Name"
username.borderStyle = UITextField.BorderStyle.none
// make sure your textField doesn't have back ground
username.backgroundColor = .clear
let bottomLine = UIView()
bottomLine.frame = CGRect(x: 0, y: view.frame.height - 1, width: view.frame.width, height: 1.0)
bottomLine.backgroundColor = UIColor.black.cgColor
// be sure you bring it to top
self.view.layer.insertSublayer(bottomLine, at:0)
username.translatesAutoresizingMaskIntoConstraints = false
username.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
username.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
username.widthAnchor.constraint(equalToConstant: 150).isActive = true
username.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
}
Try this
func bottomBorderTextField(_ textField: UIView, color: UIColor) {
// For Bottom Border
let bottomLayer = CALayer()
let frame = viewType.frame
bottomLayer.frame = CGRect(x: 0, y: frame.height - 1, width: frame.width - 2, height: 0.5)
bottomLayer.backgroundColor = color.cgColor
viewType.layer.addSublayer(bottomLayer)
}
In viewDidload()
self.bottomBorderTextField(self.txtField, color: yourTextColor)

Display UIView behind SKScene in GameViewController

I have a basic SpriteKit game.
What I basically want to do is function create_new_ui() to create a UIView and to hide it behind the scene.
override func viewDidLoad()
{
super.viewDidLoad()
create_new_ui()
if let view = self.view as! SKView?
{
// Load the SKScene from 'GameScene.sks'
let scene = MainScene()
// Set the scale mode to scale to fit the window
scene.scaleMode = .resizeFill
scene.anchorPoint = CGPoint(x: 0.5, y: 0.5)
// Present the scene
view.presentScene(scene)
view.ignoresSiblingOrder = true
view.showsFPS = true
view.showsNodeCount = true
}
}
func create_new_ui()
{
let ui_view = UIView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))
ui_view.center = CGPoint(x: self.view.frame.size.width / 2, y: self.view.frame.size.height / 2)
ui_view.backgroundColor = UIColor.red
self.view.addSubview(ui_view)
}
Can you tell me how can I move the ui_view behind the SKScene?
I tried sendSubviewToBack(_:) but had no effect. Any ideas?
There are several methods to do it. One way is directly adding it to the window after view did appear.:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
addFakeView()
}
func addFakeView(){
let fview = UIView.init(frame: CGRect.init(x: 100, y: 400, width: 100, height: 100))
fview.backgroundColor = UIColor.green
view.window?.insertSubview(fview, at: 0)
}

How to implement video controller like YouTube with rotation to landscape

I want to implement controller like YouTube. Where Top part of controller plays video and bottom remains static. And when user rotate device only Top gets rotates.
I tried to implement it with this code:
#IBOutlet weak var myView: UIView!
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
NotificationCenter.default.addObserver(self, selector: #selector(self.rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
#objc func rotated() {
if UIDeviceOrientationIsLandscape(UIDevice.current.orientation) {
UIView.animate(withDuration: 0.9, animations: {
self.myView.transform = CGAffineTransform(rotationAngle: CGFloat.pi/2)
let rect = CGRect(x: 0, y: 0, width: self.view.frame.width, height: self.view.frame.height)
self.myView.frame = rect
})
}
}
And I have this result:
Problem is controller still in portrait orientation and status bar at wrong side.
I think that there is better implementation for this thing.
Please, help
This is a simple solution for your problem,
import UIKit
class ViewController: UIViewController {
let RotatingView :UIView = UIView()
let TextLabel :UILabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.RotatingView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: (self.view.frame.size.height/3))
self.RotatingView.backgroundColor = UIColor.black
self.TextLabel.text = "Rotating View"
self.TextLabel.textColor = UIColor.white
self.TextLabel.textAlignment = .center
self.TextLabel.frame = CGRect(x: 0, y: self.RotatingView.frame.size.height/2, width: self.RotatingView.frame.width, height: 20)
self.RotatingView.addSubview(self.TextLabel)
self.view.addSubview(self.RotatingView)
NotificationCenter.default.addObserver(self, selector: #selector(rotated), name: NSNotification.Name.UIDeviceOrientationDidChange, object: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func rotated(){
switch UIDevice.current.orientation {
case .landscapeLeft, .landscapeRight:
self.RotatingView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: (self.view.frame.size.height))
self.TextLabel.frame = CGRect(x: 0, y: self.RotatingView.frame.size.height/2, width: self.RotatingView.frame.width, height: 20)
default:
self.RotatingView.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: (self.view.frame.size.height/3))
self.TextLabel.frame = CGRect(x: 0, y: self.RotatingView.frame.size.height/2, width: self.RotatingView.frame.width, height: 20)
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.setNeedsStatusBarAppearanceUpdate()
}
override var prefersStatusBarHidden : Bool {
return false
}
}

UIWebView sizeThatFits only works in delegate method

So I use a UIWebView like a UILabel with a UITextBox that changes its text via
#IBAction func textChanged(_ sender: Any){}
I size the UIWebView to the size of its content with a fixed width and a flexible height using
override func viewDidLoad() {
super.viewDidLoad()
label = WebLabel(frame: CGRect(x: 0, y: 0, width: self.view.frame.width, height: 1))
label.delegate = self
label.layer.borderColor = UIColor.black.cgColor
label.layer.borderWidth = 1.0
self.view.addSubview(label)
}
Where WebLabel is a class derived from UIWebView which implements following method :
func set(query: String)
{
let htmlString = makeHTMLString(input: (query))
self.loadHTMLString(htmlString, baseURL: nil)
self.sizeToFit()
}
So with this textChanged I get my desired result :
#IBAction func textChanged(_ sender: Any) {
label.set(query: (sender as! UITextField).text!)
label.frame = CGRect(x: label.frame.origin.x, y: label.frame.origin.y, width: label.frame.width, height: 1)
let size = label.sizeThatFits(CGSize.zero)
label.frame = CGRect(x: label.frame.origin.x, y: label.frame.origin.y, width: label.frame.width, height: size.height)
}
But I also want to set a initial html text. I do this using:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
label.set(query: "Hello World !")
label.frame = CGRect(x: label.frame.origin.x, y: label.frame.origin.y, width: label.frame.width, height: 1)
let size = label.sizeThatFits(CGSize.zero)
label.frame = CGRect(x: label.frame.origin.x, y: label.frame.origin.y, width: label.frame.width, height: size.height)
}
But that doesn't work. So the code seems to only work when triggered by user in the delegate method. How do I solve this problem ? Thanks a lot for your help !

How to implement the NavigationBar effect of AppStore ranking list page

I increase the NavigationBar height with the following code
override func viewDidLayoutSubviews() {
setUpSegmentControll()
let view = UIView(frame: CGRect(x: 0, y: 44, width: ScreenWidth, height: 40))
view.backgroundColor = UIColor.init(colorLiteralRed: 89/255, green: 89/255, blue: 89/255, alpha: 1)
segmentControll.center.x = view.center.x
view.addSubview(segmentControll)
self.navigationController?.navigationBar.addSubview(view)
}
But the segment clicked no effect,what's wrong with the code
You need to increase the size of navigation bar. Try below code it works fine
import UIKit
/*extension UINavigationBar {
open override func sizeThatFits(_ size: CGSize) -> CGSize {
var rect = self.frame;
let screenRect = UIScreen.main.bounds
rect.size.width = screenRect.size.width
rect.size.height = 104
return rect.size
}
}*/
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
self.navigationController!.navigationBar.clipsToBounds = true
}
override func viewDidAppear(_ animated: Bool) {
self.navigationController!.navigationBar.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 104.0)
}
override func viewWillDisappear(_ animated: Bool) {
self.navigationController!.navigationBar.frame = CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 64.0)
}
override func viewDidLayoutSubviews() {
let segmentControll = UISegmentedControl(items: ["1","2"])
segmentControll.frame = CGRect(x: 0, y: 5, width: 300, height: 30)
let view = UIView(frame: CGRect(x: 0, y: 64, width: UIScreen.main.bounds.size.width, height: 40))
view.backgroundColor = UIColor.init(colorLiteralRed: 89/255, green: 89/255, blue: 89/255, alpha: 1)
segmentControll.center.x = view.center.x
view.addSubview(segmentControll)
self.navigationController?.navigationBar.addSubview(view)
}
}
You have to increase the height of the navigation bar. Refer the below link to increase the height of the navigation bar
How to increase the height of UINavigationBar?

Resources