I am building an iOS Application in swift 3, where I am creating dynamic UIViews. I need to remove custom view randomly. Please help me I am stuck with this for a long time. Thanks In Advance
class ViewController: UIViewController {
var myView: subView!
var y : CGFloat!
#IBOutlet weak var addButton: UIButton!
override func viewDidLoad() {
y = 1
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func cancelbutton(_ sender: UIButton) {
myView.removeFromSuperview()
}
#IBAction func buttonAction(_ sender: Any) {
y = y + 110
myView = subView(frame: CGRect(x: 80, y: y, width: 300, height: 100))
myView.backgroundColor = UIColor.green
myView.actionButton.addTarget(self, action: (#selector(cancelbutton(_:))), for: UIControlEvents.touchUpInside)
self.view.addSubview(myView)
}
}
As you can see in the above image when i click on Close the SubView(custome View) closes, but where as MyView with green color does not go and stays there. Someone please Help.........
required init?(coder aDecoder: NSCoder)
{
super.init(coder: aDecoder)
Bundle.main.loadNibNamed("subView",owner: self, options:nil)
self.addSubview(self.views)
Bundle.main.loadNibNamed("subView",owner: self, options:nil)
self.addSubview(self.views)
}
override init(frame: CGRect)
{
super.init(frame: frame)
Bundle.main.loadNibNamed("subView", owner: self, options: nil)
views.frame = bounds
self.addSubview(self.views)
}
#IBAction func buttonAction(_ sender: Any) {
views.removeFromSuperview()
}
The thing you are doing wrong is that you add multiple views of subView that why you selected does not remove. Please modify your code like given below.
The thing I have done is that whenever you will add new subView you will also set its tag value and when you select view to remove its tag value and place an if statement on that tag value.
class ViewController: UIViewController {
var myView: subView!
var y : CGFloat!
var tag : Int = 0
#IBOutlet weak var addButton: UIButton!
override func viewDidLoad() {
y = 1
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func cancelbutton(_ sender: UIButton)
{
let selectViewTagValue : Int = sender.tag /// save the selected view tag value
for object in self.view.subviews {
if ((object is subView) && object.tag == selectViewTagValue)
{
object.removeFromSuperview()
}
}
}
#IBAction func buttonAction(_ sender: Any) {
y = y + 110
myView = subView(frame: CGRect(x: 80, y: y, width: 300, height: 100))
myView.tag = tag
myView.actionButton.tag = tag
tag = tag + 1
myView.backgroundColor = UIColor.green
myView.actionButton.addTarget(self, action: (#selector(cancelbutton(_:))), for: UIControlEvents.touchUpInside)
self.view.addSubview(myView)
}
Try to change cancel action like this:
func cancelbutton(_ sender: UIButton)
{
if let myView = sender.superview {
myView.removeFromSuperview()
}
}
Just remove the button's container view, not the global myView.
I managed to fixed the delete issue, but currently I am unable to relocate the positions the customs views, as shows in the picture below, Kindly help me with this.
Related
I want to call an action from a button which is inside a custom View. The view itself is part of a UIViewController. But when I tapped the view, nothing happens. I do not know where my mistake is, although my code looks like the ones on stackoverflow.
protocol StoreDelegate: class {
func didPressButton(_ sender: UIButton)
}
class Store: UIView {
weak var delegate:StoreDelegate?
var button: UIButton = {
let button = UIButton()
button.setTitle("button", for: .normal)
button.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
button.backgroundColor = .red
button.addTarget(self, action: #selector(buttonPress(_:)), for: .touchUpInside)
return button
}()
override init(frame: CGRect) {
super.init(frame:frame)
self.addSubview(button)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
#objc func buttonPress(_ sender: UIButton) {
delegate?.didPressButton(sender)
print("here")
}
}
And this is my ViewController:
class ViewController: UIViewController, StoreDelegate{
var testView = Store()
override func viewDidLoad() {
super.viewDidLoad()
testView.delegate = self
self.view.addSubview(testView)
}
func didPressButton(_ sender: UIButton) {
print("Hello")
}
}
Neither it prints "Hello" nor "Here". Maybe I have misunderstood the protocol/delegate pattern.
You need to set constraints or a frame to the view
testView.frame = ///////
It's the base behind receiving actions
You can implement override sizeToFit in Store class to match your needs:
override func sizeToFit() {
frame.size = button.frame.size
}
Then you can call it like:
testView.sizeToFit()
You may consider using autolayout for better sizing.
I need help to accomplish this:
Its a group of 3 photos. The first photo is the button screen before the click, the second photo is the screen after the click and the third photo is the way i've designed in the IB using stackview
I've being trying to create this and this is the result i've got so far. I still haven't created anything as the After button click image shows because of this:
My Result now
As you can see in the gif when i press the button, the UIView height constraint.constant is set to a higher value and the UIView get higher. All i want is the stripped background to get higher as well.
This is the way the view is disposed in IB.
And finally, this is the way i've coded
class LetterScreenViewController: UIViewController, ResizeWordViewDelegate {
#IBOutlet weak var youTubeView: YouTubeView!
#IBOutlet weak var phonemeView: PhonemeView!
#IBOutlet weak var wordView: WordView!
var letterPresenter: LetterPresenter?
#IBOutlet weak var heightWordViewConstraint: NSLayoutConstraint!
override func viewDidLoad() {
super.viewDidLoad()
delegateWordObj()
if let presenter = letterPresenter {
presenter.setupView()
}
}
#IBAction func dismissLetter(_ sender: Any) {
dismiss(animated: true, completion: nil)
}
func delegateWordObj() {
wordView.resizeWordViewDelegate = self
}
func didPressButton() {
if heightWordViewConstraint.constant <= 0 {
heightWordViewConstraint.constant = 30
}else{
heightWordViewConstraint.constant = 0
}
}
}
import UIKit
protocol ResizeWordViewDelegate {
func didPressButton()
}
class WordView: UIView {
#IBOutlet weak var backgroundListras: UIImageView!
#IBOutlet var WordView: UIView!
#IBOutlet weak var showWordButton: UIButton!
var resizeWordViewDelegate: ResizeWordViewDelegate!
override init(frame: CGRect) {
super.init(frame: frame)
xibInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
xibInit()
}
func xibInit() {
Bundle.main.loadNibNamed("WordView", owner: self, options: nil)
addSubview(WordView)
WordView.frame = self.bounds
WordView.round(corners: [.topLeft,.topRight], radius: 120)
WordView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
}
#IBAction func showWordButtonAction(_ sender: Any) {
resizeWordViewDelegate.didPressButton()
self.frame.size = CGSize(width: 375, height: 200)
self.backgroundListras.frame.size = CGSize(width: 375, height: 200)
}
}
I want to know a way to resize this UIView with all the content in it. After finding a solution to increase the height i'll be able to put all the others components shown when i press the button.
I believe that your goal is to create something like this:
All I had to do was change the height of the constraint programmatically
Check the solution in the project below:
https://gitlab.com/DanielLimaDF/ResizeTest.git
Important: Beware of addSubview, it can remove constraints from a View if the constraints were created before calling addSubview
I am working on iOS application in swift 3.0 where I am creating custom view with textfield and button calculate values for all text filed and display the sum of all textfield on the top totalText.
Code for MainViewController:
#IBOutlet weak var totalText: UITextField!
var totalview:[UIView]!
override func viewDidLoad() {
yvalue = 1
tag = 1
count = 1
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func actionButton(_ sender: UIButton) {
yvalue = 55 + yvalue
//for i in 0...count {
extraview = View(frame: CGRect(x: 50, y: 75+yvalue, width: 350, height: 50))
extraview.backgroundColor = UIColor(white: 1, alpha: 0.5)
extraview.layer.cornerRadius = 15
extraview.tag = tag
print("ExtraView tag=",extraview.tag)
extraview.ActionButtonsub.addTarget(self, action: (#selector(cancelbutton(_:))), for: UIControlEvents.touchUpInside)
extraview.textFiled.addTarget(self, action: #selector(didChangeTexts(textField:)), for: .editingChanged)
extraview.textFiled.tag = tag
print("text tag=",extraview.textFiled.tag)
self.view.addSubview(extraview)
count = count + 1
tag = tag + 1
//}
}
func cancelbutton(_ sender: UIButton) {
extraview.removeFromSuperview()
}
func didChangeTexts(textField: UITextField) {
totalText.text = extraview.textFiled.text
}
Code for UIView:
class View: UIView {
#IBOutlet var subView: UIView!
#IBOutlet weak var textFiled: UITextField!
#IBOutlet weak var ActionButtonsub: UIButton!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
Bundle.main.loadNibNamed("View",owner: self, options:nil)
self.addSubview(self.subView)
}
override init(frame: CGRect) {
super.init(frame: frame)
Bundle.main.loadNibNamed("View", owner: self, options: nil)
subView.frame = bounds
self.addSubview(self.subView)
}
}
Sample Output
If you think #Scriptable way is complex then go like below..
Simple way, you can add those textfields into one collection while creating & looping it when you need to do something.
Something like this should work, may need a little modification.
You just need to iterate through the subviews, get the textfield for each view, convert to double value and add them up along the way.
func calculateTotal() -> Double {
var total: Double = 0.0
for subview in self.view.subviews {
if let v = subview as? View, !v.textFiled.isEmpty {
total += Double(v.textFiled.text)
}
}
return total
}
An alternative is applying filter, flatMap and reduce functions
let sum = (view.subviews.filter{$0 is View} as! [View]) // filters all `View` instances
.flatMap{$0.textFiled.text} // maps all text properties != nil
.flatMap{Double($0)} // maps all values which are convertible to Double
.reduce(0.0, {$0 + $1}) // calculates the sum
I have multiple subviews in my main view controller, I am using a delete button to remove one subview at a time. I am trying to allow the user to bring back the view that was deleted, but the view is not coming back. Any thoughts? In Swift.
#IBOutlet var tornView: UIView!
var deleted = 1
// Delete Button
#IBAction func deleteViewButton(sender: AnyObject) {
if deleted == 1 {
tornView.removeFromSuperview()
deleted = 2
}
}
// Brings View to Screen
#IBAction func showTornAnnotation(sender: AnyObject) {
if toggleState == 1 {
firstSlider.hidden = false
tornView.hidden = false
toggleState = 2
if deleted == 2 {
view.addSubview(tornView)
}
}
else {
firstSlider.hidden = true
tornView.hidden = true
toggleState = 1
}
}
If you want IBOutlet to be removed from the superView and get it added back then you should always use strong references to your IBOutlet. Being said you should also keep the position of the removed view so that you can use it when you are ready to add it back.
Edit: Sample code
#IBOutlet var customView: UIView!
var customViewFrame: CGRect?
override func viewDidLoad() {
super.viewDidLoad()
customView.backgroundColor = UIColor.blueColor()
}
#IBAction func remove(sender: AnyObject) {
customViewFrame = customView.frame
customView.removeFromSuperview()
}
#IBAction func add(sender: AnyObject) {
if let rect = customViewFrame {
customView = UIView.init(frame: rect)
customView.backgroundColor = UIColor.blueColor()
view.addSubview(customView)
view.bringSubviewToFront(customView)
}
}
I am trying to create a custom UIView and display it as a pop up in my main View using Swift.
My Custom UIView code is
class DatePopUpView: UIView {
var uiView:UIView?
override init() {
super.init()
self.uiView = NSBundle.mainBundle().loadNibNamed("DatePopUpView", owner: self, options: nil)[0] as? UIView
}
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
required override init(frame: CGRect) {
super.init(frame: frame)
}
}
And I am Calling it in my main view as:
#IBAction func date_button_pressed (sender : AnyObject?) {
var popUpView = DatePopUpView()
var centre : CGPoint = CGPoint(x: self.view.center.x, y: self.view.center.y)
popUpView.center = centre
popUpView.layer.cornerRadius = 10.0
let trans = CGAffineTransformScale(popUpView.transform, 0.01, 0.01)
popUpView.transform = trans
self.view .addSubview(popUpView)
UIView .animateWithDuration(0.5, delay: 0.0, options: UIViewAnimationOptions.CurveEaseInOut, animations: {
popUpView.transform = CGAffineTransformScale(popUpView.transform, 100.0, 100.0)
}, completion: {
(value: Bool) in
})
}
But popUp is not Coming. I used breakpoint and noticed that value is getting assigned to my popUpView but still it is not displayed on my main View. Please Help
Please Note: I am using StoryBoard for my mainView and custom View i have made using xib.
Without additional description on what you are attempting to do, may I suggest something like the code below? Basically, you can use .hidden feature of a view (or any other control) to show/hide the view. You can set the size and positioning of the view to be popped by using the layout editor.
import UIKit
class ViewController: UIViewController {
var popped = false
var popupBtnTitle = "Show Popup"
#IBAction func popupButton(sender: UIButton) {
popped = !popped
anotherView.hidden = !popped
popupBtnTitle = popped ? "Hide Popup" : "Show Popup"
popupButtonOutlet.setTitle(popupBtnTitle, forState: UIControlState.Normal)
}
#IBOutlet weak var popupButtonOutlet: UIButton!
#IBOutlet weak var anotherView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
popped = false
anotherView.hidden = !popped
popupButtonOutlet.setTitle(popupBtnTitle, forState: UIControlState.Normal)
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}