I've been searching all around the other questions but none of the solutions I've read worked for me.
I have this code I need to modify so that when the button's title changes, it still appears to be aligned with some other items in the table. The button was declared programmatically as shown below:
internal func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
if section % 2 != 0 {
let frame : CGRect = tableView.frame
btnSelectAll = UIButton(frame: CGRect(x: frame.size.width-92, y: 0 , width: 100, height: 30))
btnSelectAll.setTitle(btnTitle, for: .normal)
btnSelectAll.setTitleColor(UIColor.blue, for: .normal)
let lblTitle : UILabel = UILabel(frame: CGRect(x: 19, y: 0, width: 120, height: 30))
btnSelectAll.addTarget(self, action:#selector(selectAllClicked(sender:)), for: .touchUpInside)
lblTitle.text = Constants.FILTER_DEPARTMENT_SECTION
lblTitle.font = UIFont.boldSystemFont(ofSize: 17)
let headerView: UIView = UIView(frame: CGRect(x: 0, y: 0, width: frame.width, height: frame.height))
headerView.backgroundColor = UIColor.white
headerView.addSubview(btnSelectAll)
headerView.addSubview(lblTitle)
return headerView
}
return nil
}
I tried to change it like so here:
if filter[Constants.FILTER_DEPARTMENT_SECTION]?.count == department.count {
if let btnSelectAll = btnSelectAll {
let frame : CGRect = tableView.frame
let newFrame = CGRect(x: frame.size.width-150, y: 0 , width: 100, height: 30)
btnSelectAll.frame = newFrame
btnSelectAll.setTitle(Constants.DESELECT_ALL, for: .normal)
btnSelectAll.setNeedsDisplay()
}
}
Unfortunately I still can't get it to move.
Use btnSelectAll.sizeToFit(),
As Apple says:
Call this method when you want to resize the current view so that it uses the most appropriate amount of space. Specific UIKit views resize themselves according to their own internal needs. In some cases, if a view does not have a superview, it may size itself to the screen bounds. Thus, if you want a given view to size itself to its parent view, you should add it to the parent view before calling this method.
Related
I am trying to overlap the button on two or more views. So when I add this on the first view it is not showing on the second view so I want one button must shown on two views.
You can make two views and embed second view to first and then button to second View and can play with its Y axis
class overlapViewcontroller:UIViewController {
private let firstView:UIView = {
let view = UIView(frame: CGRect(x: 10,
y: 100,
width: 350,
height: 50))
view.backgroundColor = .green
return view
}()
private let secondView:UIView = {
let view = UIView(frame: CGRect(x: 10,
y: 10,
width: 330,
height: 30))
view.backgroundColor = .purple
return view
}()
private let button:UIButton = {
let button = UIButton(frame: CGRect(x: 10,
y: -5,
width: 310,
height: 20))
button.setTitle("Button", for: .normal)
button.backgroundColor = .systemOrange
return button
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBackground
view.addSubview(firstView)
firstView.addSubview(secondView)
secondView.addSubview(button)
}
}
Did you try this? You need to add the button to the container subview and add
this line container.bringSubviewToFront(button)
https://www.hackingwithswift.com/example-code/uikit/how-to-bring-a-subview-to-the-front-of-a-uiview
You need either to
add the button as the very last so that it can be the top one on the subviews stack
or to apply the superview.bringSubviewToFront(button)
I am building an app and I am required to have 3 tabs if you click on the first tab, its a tableview, second tab a different tableview, third tab, TextView, here is an image of what I am trying to do:
Every time I google looking for examples of something like this, I get referred to UITabBarController, I don't think a tab bar is what I am looking for.
What you are looking for is called Segmented Control (UISegmentedControl).
You can see it in Action natively e.g. in both the Apple iTunes and Health App.
Instead of performing segues to different views with the UITabBarController, you can, using Interface Builder, connect it to your UIViewController like so
#IBOutlet weak var segmentedControl: UISegmentedControl!
and in
viewDidLoad() {
switch segmentedControl.selectedIndex {
case 0: // Do something on your first picture
someFunction()
case 1: // Do something on your second picture
performSegue(withIdentifier: "your identifier here", sender: nil)
case 2: // Do something on your third picture
image.isHidden = true
button.isEnabled = false
default: break
}
... etc. You could also initiate different View Controllers instead of manipulating just one View, which you can then access via segues.
Please see official Swift doc # https://developer.apple.com/documentation/uikit/uisegmentedcontrol?changes=_3
I would create this layout programmatically. You want a custom look to it so I do not think the standard controls are your best option.
Here is a playground to get you started on one way this could be achieved:
import UIKit
import PlaygroundSupport
class ViewController: UIViewController {
let view1 = UIView(frame: CGRect(x: 0, y: 100, width: 768, height: 924))
let view2 = UIView(frame: CGRect(x: 0, y: 100, width: 768, height: 924))
let view3 = UIView(frame: CGRect(x: 0, y: 100, width: 768, height: 924))
override func viewDidLoad() {
super.viewDidLoad()
self.view.frame = CGRect(x: 0, y: 0, width: 768, height: 1024)
self.view.backgroundColor = .black
// View to have a border around the buttons
let box = UIView(frame: CGRect(x: 40, y: 20, width: 300, height: 50))
box.layer.borderColor = UIColor.white.cgColor
box.layer.borderWidth = 2
self.view.addSubview(box)
// Tab buttons
let button1 = UIButton(frame: CGRect(x: 40, y: 20, width: 100, height: 50))
button1.setTitle("Orange", for: .normal)
button1.tag = 1
button1.addTarget(self, action: #selector(tabTouched(sender:)), for: .touchUpInside)
self.view.addSubview(button1)
let button2 = UIButton(frame: CGRect(x: 140, y: 20, width: 100, height: 50))
button2.setTitle("Blue", for: .normal)
button2.tag = 2
button2.addTarget(self, action: #selector(tabTouched(sender:)), for: .touchUpInside)
self.view.addSubview(button2)
let button3 = UIButton(frame: CGRect(x: 240, y: 20, width: 100, height: 50))
button3.setTitle("Green", for: .normal)
button3.tag = 3
button3.addTarget(self, action: #selector(tabTouched(sender:)), for: .touchUpInside)
self.view.addSubview(button3)
// Tab Views
view1.backgroundColor = .orange
self.view.addSubview(view1)
view2.backgroundColor = .blue
view2.alpha = 0
self.view.addSubview(view2)
view3.backgroundColor = .green
view3.alpha = 0
self.view.addSubview(view3)
}
// When each of the buttons are tapped we will hide or show the correct tab's view
#objc func tabTouched(sender: UIButton) {
if sender.tag == 1 {
UIView.animate(withDuration: 0.3) {
self.view1.alpha = 1
self.view2.alpha = 0
self.view3.alpha = 0
}
} else if sender.tag == 2 {
UIView.animate(withDuration: 0.3) {
self.view1.alpha = 0
self.view2.alpha = 1
self.view3.alpha = 0
}
} else if sender.tag == 3 {
UIView.animate(withDuration: 0.3) {
self.view1.alpha = 0
self.view2.alpha = 0
self.view3.alpha = 1
}
}
}
}
PlaygroundPage.current.needsIndefiniteExecution = true
PlaygroundPage.current.liveView = ViewController()
You can copy and paste this into an empty playground to see it in action. Essentially this is showing or hiding the appropriate views based on which button is selected. You can swap out the views for view controllers if you so desire.
I've got a small question: is it possible somehow (without storyboard) to create a little view at the top of the screen (if there's a navigationbar, then under that), that displays errors / responses if needed?
Without creating views on every single viewController I made, just by code?
Or is there some extension you could recommend?
For example: "No Internet Connection"
You can check this answer - https://stackoverflow.com/a/49129636/6080920
Code required
extension UIViewController
{
func showNotificationView(message : String)
{
//base View
let baseView = UIView(frame: CGRect(x: 20, y: self.view.frame.size.height-(self.view.frame.size.height*0.15), width: self.view.frame.size.width-40, height: self.view.frame.size.height*0.08))
baseView.backgroundColor = UIColor.gray
baseView.clipsToBounds=true
self.view.addSubview(baseView)
//Image View
let imageView = UIImageView(image: UIImage(named: "RM_3"))
imageView.clipsToBounds=true
imageView.frame = CGRect(x: 0, y: 0, width: baseView.frame.size.width*0.2, height: baseView.frame.size.height)
baseView.addSubview(imageView)
//Label
let textLabel = UILabel(frame: CGRect(x: baseView.frame.size.width*0.2+10, y: 0, width: baseView.frame.size.width, height: baseView.frame.size.height))
textLabel.textColor = UIColor.white
textLabel.backgroundColor = UIColor.clear
textLabel.textAlignment = .left;
textLabel.numberOfLines = 0
textLabel.font = UIFont(name: "Montserrat-Light", size: 12.0)
textLabel.text = message
baseView.addSubview(textLabel)
}
}
Usage
#IBAction func navigate(_ sender: Any) {
self.showNotificationView(message: "hihihihh")
}
I have made a custom view called SignView and added to another customView called mainSignView which is inside an scrollview called getFormView but when I sign on the signView it scrolls and I cannot do any sign help me to overcome this please!
Here is what I have
#objc func pressedSignViewAction(_ sender: UILabel) {
self.signViewElement = "signView1"
uniY += 60
mainSignView = UIView(frame: CGRect(x: 20, y: uniY, width: 250, height: 250))
mySignViewName = UILabel(frame: CGRect(x: 20, y: 10, width: 200, height: 30))
let signLabel = UILabel(frame: CGRect(x: 20, y: 50, width: 200, height: 30))
signView = YPDrawSignatureView(frame: CGRect(x: 10, y: 90, width: 230, height: 100))
signView.backgroundColor = .white
signLabel.text = "Signature"
mainSignView.backgroundColor = .green
mySignViewName.text = self.signViewNameFD
self.signViewNameElement = self.signViewNameFD
cancelButton = UIButton(frame : CGRect(x: 20, y: 200, width: 100, height: 25))
cancelButton.addTarget(self, action: #selector(pressedSignClearAction(_:)), for: .touchUpInside)
cancelButton.setTitle("Clear",for: .normal)
cancelButton.setTitleColor(UIColor.red, for: .normal)
uniY += 170
self.view.addSubview(getFormView)
//self.getFormView.addSubview(signLabel)
self.getFormView.addSubview(mainSignView)
self.mainSignView.addSubview(signLabel)
self.mainSignView.addSubview(signView)
self.mainSignView.addSubview(mySignViewName)
self.mainSignView.addSubview(cancelButton)
self.enterSignViewTitle()
self.updateScrollY()
}
#objc func pressedSignClearAction(_ sender: UIButton) {
self.signView.clear()
}
From YPDrawSignatureView Documentation:
// MARK: - Delegate Methods
// The delegate functions gives feedback to the instanciating class. All functions are optional,
// meaning you just implement the one you need.
// didStart() is called right after the first touch is registered in the view.
// For example, this can be used if the view is embedded in a scroll view, temporary
// stopping it from scrolling while signing.
func didStart() {
print("Started Drawing")
yourScroll.isScrollEnabled = false
}
// didFinish() is called rigth after the last touch of a gesture is registered in the view.
// Can be used to enable scrolling in a scroll view if it has previous been disabled.
func didFinish() {
print("Finished Drawing")
yourScroll.isScrollEnabled = true
}
I am writing my first Swift app for quiz. Each question has random way to render on screen as below screenshot.
I am programming app without story board ie. programmatically. I want to create simple pagination flow for each question within single viewcontroller without using Collocationview, Tableview or navigation.
What I did so far? I have simple viewcontroller with UIView() added as subview. I am adding question components dynamically. Now once user click on continue I wanted remove subview and add new subview with new question. I am able to remove subview but contents on subview seems to be still there as I can see its overwriting.
To get more clarification please view my code.
import UIKit
class QuizController: UIViewController {
let subView = UIView()
var currentQuestion:Int = 1;
let questions = ["This is question 1", "Hello to question 2", "Question 3"]
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = .white
setup_layout()
}
func setup_layout(){
let closeBtn = UIButton(frame: CGRect(x: 5, y: 10, width: 200, height: 50))
closeBtn.backgroundColor = UIColor.red
closeBtn.setTitle("Close", for: .normal)
closeBtn.addTarget(self, action: #selector(close), for: .touchUpInside)
view.addSubview(closeBtn)
//dynamic view
create_subview()
}
func nextQuestion(){
print("Show next")
if let viewWithTag = self.view.viewWithTag(currentQuestion) {
viewWithTag.removeFromSuperview()
currentQuestion += 1;
create_subview()
} else {
print("No!")
}
}
func create_subview(){
let heightOfView = view.frame.size.height
let widthOfView = view.frame.size.width
subView.tag = currentQuestion
subView.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.2)
subView.frame = CGRect(x: 0, y: 60, width: self.view.frame.width, height: heightOfView - 60)
self.view.addSubview(subView)
let txtLabel1 = UILabel(frame: CGRect(x: 35, y: 120, width: widthOfView , height: 20))
txtLabel1.text = questions[currentQuestion-1]
txtLabel1.font = txtLabel1.font.withSize(12)
subView.addSubview(txtLabel1)
let nextBtn = UIButton(frame: CGRect(x: 5, y: 300, width: 200, height: 50))
nextBtn.backgroundColor = UIColor.red
nextBtn.setTitle("Continue", for: .normal)
nextBtn.addTarget(self, action: #selector(nextQuestion), for: .touchUpInside)
subView.addSubview(nextBtn)
}
func close(){
self.dismiss(animated: true, completion: nil)
}
}
And this is what I see which I click continue.
NOTE: Initially thought using Collocation or Table view will be more appropriate as I can set to scroll horizontally for each question and fetch questions using REST API and place to each cell. But I want to present next screen to user only once then click on continue. I guess with collectionview user can move to next screen on swipe.
Just found the answer. I assumed removing subview will also remove all components on subview by itself ie. UILable and UIButton in my case.
I have to remove them separately.
for subview in self.subView.subviews {
subview.removeFromSuperview()
}
Now i can add tag to components and remove like this:
for subview in self.subView.subviews {
if (subview.tag == 1) {
subview.removeFromSuperview()
}
}
Why are you removing superviews and adding again and again??
Simply change UILabel.text :)