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 !
Related
I'm trying to change UIButton but it doesn't work. My code is like this.
#IBAction func addButtonTapped(_ sender: Any) {
print(defaultAddButton.center)
let buttonPos = CGPoint(x: defaultAddButton.frame.midX, y: defaultAddButton.frame.midY)
let width = self.view.bounds.width
let height: CGFloat = 100
let uiView = SubCollecionView(frame: CGRect(x: buttonPos.x - width / 2, y: buttonPos.y - height / 2, width: width, height: height))
self.view.addSubview(uiView)
self.defaultAddButton.center.y += 200
}
SubCollectionView is my custom view. Above code works without self.view.addSubview(uiView) line. I can't understand why it doesn't work. Thank you in advance!
do not fully understand your problem, but can suggest that you have a problem with animation, with this line of code:
self.defaultAddButton.center.y += 200
The above code doesn't work because you need to update the view to update its layout immediately, use this method to update view "layoutIfNeeded()"
Example of code:
class VC: UIViewController {
lazy var buttonAction: UIButton = {
let view = UIButton()
view.translatesAutoresizingMaskIntoConstraints = false
view.setTitle("Action", for: .normal)
view.setTitleColor(#colorLiteral(red: 1, green: 1, blue: 1, alpha: 1), for: .normal)
view.backgroundColor = .blue
view.addTarget(self, action: #selector(action(_:)), for: .touchUpInside)
return view
}()
#objc func action(_ sender: UIButton) {
print("action")
print(buttonAction.center)
let buttonPos = CGPoint(x: buttonAction.frame.midX, y: buttonAction.frame.midY)
let width = self.view.bounds.width
let height: CGFloat = 100
let uiView = MediaPlayer(frame: CGRect(x: buttonPos.x - width / 2, y: buttonPos.y - height / 2, width: width, height: height))
self.view.addSubview(uiView)
self.buttonAction.center.y += 200
UIView.animate(withDuration: 1.0) {
self.view.layoutIfNeeded()
}
}
func setupButton() {
self.view.addSubview(buttonAction)
buttonAction.centerXAnchor.constraint(equalTo: self.view.centerXAnchor).isActive = true
buttonAction.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -70).isActive = true
buttonAction.heightAnchor.constraint(equalToConstant: 50).isActive = true
buttonAction.widthAnchor.constraint(equalToConstant: 100).isActive = true
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .gray
setupButton()
}
}
You can try setting changes/frame in view over
viewDidLayoutSubviews
You should call layoutIfNeeded() after this.
#IBAction func addButtonTapped(_ sender: Any) {
print(defaultAddButton.center)
let buttonPos = CGPoint(x: defaultAddButton.frame.midX, y: defaultAddButton.frame.midY)
let width = self.view.bounds.width
let height: CGFloat = 100
let uiView = SubCollecionView(frame: CGRect(x: buttonPos.x - width / 2, y: buttonPos.y - height / 2, width: width, height: height))
self.view.addSubview(uiView)
self.defaultAddButton.center.y += 200
self.view.layoutIfNeeded()
}
If this doesn't work. Please try to call UI modification code inside the main queue.
#IBAction func addButtonTapped(_ sender: Any) {
print(defaultAddButton.center)
DispatchQueue.main.async {
let buttonPos = CGPoint(x: defaultAddButton.frame.midX, y: defaultAddButton.frame.midY)
let width = self.view.bounds.width
let height: CGFloat = 100
let uiView = SubCollecionView(frame: CGRect(x: buttonPos.x - width / 2, y: buttonPos.y - height / 2, width: width, height: height))
self.view.addSubview(uiView)
self.defaultAddButton.center.y += 200
self.view.layoutIfNeeded()
}
}
Is it possible to change the UINavigationBar height in ios 11?
I've tried this:
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let height: CGFloat = 50 //whatever height you want to add to the existing height
let bounds = self.navigationController!.navigationBar.bounds
self.navigationController?.navigationBar.frame = CGRect(x: 0, y: 0, width: bounds.width, height: bounds.height + height)
}
and this:
extension UINavigationBar {
override open func sizeThatFits(_ size: CGSize) -> CGSize {
return CGSize(width: UIScreen.main.bounds.width, height: 100)
}
}
and none of them seem to work.
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?
I want to set the navigationItem's titleView with image and text like the picture below:
How do I achieve that?
More specifically, I am trying to do this in Swift.
The condition, your controller must have its navigation controller:
Using my code I write below, the result is like this:
In your view controller ,try my code below:
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
initUI()
}
// MARK: - init
func initUI() {
let rect:CGRect = CGRect.init(origin: CGPoint.init(x: 0, y: 0), size: CGSize.init(width: 64, height: 64))
let titleView:UIView = UIView.init(frame: rect)
/* image */
let image:UIImage = UIImage.init(named: "01.jpg")!
let image_view:UIImageView = UIImageView.init(image: image)
image_view.frame = CGRect.init(x: 0, y: 0, width: 30, height: 30)
image_view.center = CGPoint.init(x: titleView.center.x, y: titleView.center.y - 10)
image_view.layer.cornerRadius = image_view.bounds.size.width / 2.0
image_view.layer.masksToBounds = true
titleView.addSubview(image_view)
/* label */
let label:UILabel = UILabel.init(frame: CGRect.init(x: 0, y: 30, width: 64, height: 24))
label.text = "Hello"
label.font = UIFont.systemFont(ofSize: 12)
label.textAlignment = .center
titleView.addSubview(label)
self.navigationItem.titleView = titleView
}
How to create some space at the beginning of a text field using swift?
I looked at the post
padding of text field
I don't understand what the subclass is doing and how do I use that class to padding.
Thank you very much
https://stackoverflow.com/a/27066764/846780
This answer is very clear,
If you subclass UITextField you can override textRectForBounds, editingRectForBounds and placeholderRectForBounds. These methods just allow you to add a rect (frame) to your textfield's label.
newBounds method create the rect (frame) that will be added to textfield's label.
Finally your padding is: let padding = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5);
Now you have a custom UITextField that has a custom padding.
If you create your new subClass like this class MyTextField: UITextField for example, you only need to change the class of the UITextField that you've added into IB file.
Complementing the answer of klevison-matias this is the code I use when I want to add a padding to my TextField in Swift 3
//UITextField : override textRect, editingRect
class LeftPaddedTextField: UITextField {
override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + 10, y: bounds.origin.y, width: bounds.width, height: bounds.height)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + 10, y: bounds.origin.y, width: bounds.width, height: bounds.height)
}
}
Then in my TextField I use in this way:
let emailTextField: LeftPaddedTextField = {
let textField = LeftPaddedTextField()
textField.placeholder = "Enter email"
textField.layer.borderColor = UIColor.lightGray.cgColor
textField.layer.borderWidth = 1
textField.keyboardType = .emailAddress
return textField
}()
let passwordTextField: LeftPaddedTextField = {
let textField = LeftPaddedTextField()
textField.placeholder = "Enter password"
textField.layer.borderColor = UIColor.lightGray.cgColor
textField.layer.borderWidth = 1
textField.isSecureTextEntry = true
return textField
}()
Create TextField outlet and use following code. Say "nameTextField" has to add padding.
let paddingView = UIView(frame: CGRectMake(x: 0, y: 0, width: 30, height: 30))
nameTextField.leftView = paddingView
nameTextField.leftViewMode = .always
nameTextField.placeholder = "Enter Name"
You can add Image in paddingView.
Based on #Jorge Casariego's answer I came up with this solution.
You can set PaddedTextField class and the desired padding through the Interface Builder!
class PaddedTextField: UITextField {
#IBInspectable var padding: CGFloat = 0
override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + padding, y: bounds.origin.y, width: bounds.width - padding * 2, height: bounds.height)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + padding, y: bounds.origin.y, width: bounds.width - padding * 2, height: bounds.height)
}
}
full code sample:
make sure your TextField points to RoundedTextField via Story board
import UIKit
class RoundedTextField: UITextField {
override func awakeFromNib() {
// add rounded corner
self.layer.cornerRadius = 15.0
self.clipsToBounds = false
super.awakeFromNib()
}
// For the padding from the left
override func textRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + 15.0, y: bounds.origin.y, width: bounds.width, height: bounds.height)
}
override func editingRect(forBounds bounds: CGRect) -> CGRect {
return CGRect(x: bounds.origin.x + 15.0, y: bounds.origin.y, width: bounds.width, height: bounds.height)
}
}