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
Related
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 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.
I'm very new to swift so sorry if this is a basic question or I'm doing something terribly wrong. I've been having some issues trying to add a subview when touching a row on a tableview and have been working off of this page: http://myxcode.net/2015/11/07/adding-a-subview-using-a-xib-and-storyboard/
Here's the relevant code I have so far (I removed some of the tableview logic because that works fine):
Subview Class
class ConfirmTeamView: UIView, UITableViewDataSource, UITableViewDelegate {
#IBOutlet weak var teamListTableView2: UITableView!
#IBOutlet weak var confirmButton2: UIButton!
#IBOutlet weak var cancelButton2: UIButton!
var playerList: [Player]?
var view: UIView!
init(pList: [Player]) {
self.playerList = pList
super.init(frame: CGRectMake(20, 100, 385, 339))
setup()
teamListTableView2.delegate = self
teamListTableView2.dataSource = self
let playerListTableCellNib = UINib(nibName: "PlayerListTableViewCell", bundle: nil)
teamListTableView2.registerNib(playerListTableCellNib, forCellReuseIdentifier: "PlayerListTableViewCell")
}
required init?(coder aDecoder: NSCoder) {
self.playerList = nil
super.init(coder: aDecoder)
setup()
}
func setup() {
view = loadViewFromNib()
view.frame = bounds
view.autoresizingMask = [UIViewAutoresizing.FlexibleHeight,UIViewAutoresizing.FlexibleWidth]
addSubview(view)
}
func loadViewFromNib () -> UIView
{
let bundle = NSBundle(forClass: self.dynamicType)
let nib = UINib(nibName: "ConfirmTeamView", bundle: bundle)
//this line I think is causing a stack overflow, any idea why?
let thisview = nib.instantiateWithOwner(self, options: nil)[0] as! UIView
return thisview
}
}
and then in my viewController (I again removed some tableview methods for ease of reading):
class ChooseExistingTeamViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var TeamListTableView: UITableView!
var existingTeamsArray = [Team]()
var confirmTeamUI : ConfirmTeamView!
override func viewDidLoad() {
super.viewDidLoad()
TeamListTableView.delegate = self
TeamListTableView.dataSource = self
let testPlayer1 = Player(name: "John", number: 24)
let testPlayer2 = Player(name: "Smith", number: 50)
let testTeam = Team(name: "myTeam", players: [testPlayer1, testPlayer2])
existingTeamsList = [testTeam]
}
override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() }
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// This is where I load the subview
TeamListTableView.userInteractionEnabled = false
let selectedTeam = existingTeamsList[indexPath.row]
let confirmTeamUI = ConfirmTeamView(pList: selectedTeam.players)
confirmTeamUI.cancelButton2.addTarget(self, action: "cancelPressed:", forControlEvents: UIControlEvents.TouchUpInside)
let viewWidth = self.view.frame.width
let xWidth = viewWidth - 40
let yHeight = 200
confirmTeamUI.frame = CGRect(x: 20, y: 100, width: Int(xWidth), height: yHeight)
self.view.addSubview(confirmTeamUI)
}
func cancelPressed(sender: UIButton) {
// self.confirmTeamUI.view.removeFromSuperview() [This line throws an exception for unwrapping an optional value]
if self.confirmTeamUI != nil { self.confirmTeamUI.removeFromSuperview() }
else { print("Confirm Team is nil") }
// pressing the cancel button runs the else case
}
Any advice would be very appreciated and please let me know if you need more!
I need to develop custom UISlider using swift. The problem is I don't know how to make sure label following slider's thumbnail like following below:
My code so far
import Foundation
import UIKit
class Slider: UISlider {
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.layer.borderColor = UIColor.redColor().CGColor
self.layer.borderWidth = 0.2
self.tintColor = UIColor.redColor()
}
}
Probably is worth to take a look at this method, this can't be called directly but you can use it while subclassing
func thumbRectForBounds(_ bounds: CGRect,
trackRect rect: CGRect,
value value: Float) -> CGRect
More info also on this question and here
I had the exact thing for audio files.
The protocol is used to inform the player when user changes the value of the slider.
func updateSliderPosition(position: Float)
is called every half second by the player to change position of the slider current value.
import UIKit
protocol AudioSliderControlDelegate: class
{
func audioSliderControlDdiChangeValue(sender: AudioSliderControl, value: Float)
}
class AudioSliderControl: UIControl
{
#IBOutlet weak var slider: UISlider!
#IBOutlet weak var currentPositionLabel: UILabel!
#IBOutlet weak var totalDurationLabel: UILabel!
weak var delegate: AudioSliderControlDelegate?
private var totalLenght: Double?
override func awakeFromNib()
{
super.awakeFromNib()
backgroundColor = UIColor.clevooOrange()
slider.addTarget(self, action: "sliderValueChanged:", forControlEvents: .ValueChanged)
self.addSeperatorToTop()
}
//MARK:
//MARK: - Setup
func setupForDuration(duration: Double)
{
totalLenght = duration
currentPositionLabel.text = Double(0).formattedDuration()
totalDurationLabel.text = (duration + 0.5).formattedDuration()
slider.setValue(0, animated: false)
}
func updateSliderPosition(position: Float)
{
self.currentPositionLabel.text = (totalLenght! * Double(position)).formattedDuration()
self.slider.value = position
}
//MARK:
//MARK: - Notification
func sliderValueChanged(slider: UISlider)
{
self.currentPositionLabel.text = (totalLenght! * Double(slider.value)).formattedDuration()
delegate?.audioSliderControlDdiChangeValue(self, value: slider.value)
}
}
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.
}
}