Change the value of another class (Extension) with argument - ios

A function whose argument is used for Extension of another class is described.
I want to change the value of the UIView property (alpha) that exists in that function "at the button tap in another class".
However, this function can be changed at ViewDidLoad time.
How can I change the value when tapping buttons?
If possible please write the code.
ViewController Class
class ViewController: UIViewController {
#IBOutlet weak var vHome: UICollectionView!
#IBOutlet weak var vSearch: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
selectRd(rd: 3) //This time can change calue of alpha.
}
}
extension ViewController {
func selectRd(rd reader:Int){
var animateView:UIView!
let animateVHome = vHome
let animateVSearch = vSearch
UIView.animate(withDuration: 0.3, delay: 0.0, animations: {
animateVHome.alpha = 0.0
animateVSearch.alpha = 0.0
}, completion: nil)
switch reader {
case 2:
animateView = animateVHome
case 3:
animateView = animateVSearch
default:
break
}
UIView.animate(withDuration: 0.3, delay: 0.3, animations: {
animateView.alpha = 1.0
}, completion: nil)
}
}
Another Class
class Another{
#objc func buttonTapped(sender : HeaderButton) {
let vC = ViewController
vC.selectRd(rd: 2) //This time can not!!
}
}
Please comment if you can not understand the question.

The problem is that you can't access a function of a class if its currently active , as this will result in a crash , so Add a var in viewControler
class ViewController: UIViewController {
#IBOutlet weak var vHome: UICollectionView!
#IBOutlet weak var vSearch: UICollectionView!
var index:Int?
override func viewDidLoad() {
super.viewDidLoad()
selectRd(rd: self.index) //This time can change calue of alpha.
}
}
..
class Another{
#objc func buttonTapped(sender : HeaderButton) {
let vC = ViewController
vC.index = 2 //This time can not!!
}
}

Related

Problems Updating View with Swift 5

I am having some trouble updating my secondViewController view in Xcode using Swift 5. I want my app to add two numbers together and show the result in the second ViewController. Although it works the first time, if I return to my previous view and change the numbers, the view does not update.
I tried using viewWillAppear, viewWillDisappear, amongst others, including NSNotificationCenter addObserve, but I have had no luck whatsoever.
Do you have any recommendations? Am I missing something?
Please see below for the code and a screenshot of my ViewControllers:
//
// ViewController.swift
//
import UIKit
var result = ""
var resultFinal = Float(result)
let finalResult = resultFinal!
class ViewController: UIViewController {
#IBOutlet weak var firstNumber: UITextField!
#IBOutlet weak var secondNumber: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
func getResult()-> Float{
guard let fNumber = firstNumber.text else {
return 0
}
let firstFloat = Float(fNumber)
guard let sNumber = secondNumber.text else {
return 0
}
let secondFloat = Float(sNumber)
let sumNumber: Float = firstFloat! + secondFloat!
return sumNumber
}
#IBAction func submitSum(_ sender: Any) {
resultFinal = getResult()
print(resultFinal!)
}
}
//
// secondViewController.swift
//
import UIKit
class secondViewController: UIViewController {
#IBOutlet weak var test: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
self.test.text!=""
// Do any additional setup after loading the view.
}
override func viewWillAppear(_ animated: Bool) {
test.text = String(finalResult)
}
}
Screenshot:
Thanks.
Your problem is with the global variables. It seems from your code that you expect these three to reevaluate every time one of them changes:
var result = ""
var resultFinal = Float(result)
let finalResult = resultFinal!
For example, if you set resultFinal = 4, then finalResult will equal 4. However, those variables only evaluate once––the first time. You can simplify your use of these variables significantly. Replace these three with:
var result: Float?
Then, in ViewController:
class ViewController: UIViewController {
#IBOutlet weak var firstNumber: UITextField!
#IBOutlet weak var secondNumber: UITextField!
func getResult() -> Float {
guard let number1 = Float(firstNumber.text ?? "0") ?? 0
guard let number2 = Float(secondNumber.text ?? "0") ?? 0
return number1 + number2
}
#IBAction func submitSum(_ sender: Any) {
result = getResult()
}
}
Note: I simplified getResult and made it treat empty fields as 0.
In SecondViewController:
class SecondViewController: UIViewController {
#IBOutlet weak var test: UITextField!
override func viewWillAppear(_ animated: Bool) {
test.text = String(result ?? 0)
}
}
Note: self.test.text!="" doesn't really do anything, so I removed it.

Swift iOS -How to remove a view controller of a segmentControl from memory?

I have a segmentControl with 2 indexes. It is inside a parent view controller. The parent view controller has 2 containerViews that each have an embedded viewController.
parentVC
|
segmentedControll _vcZero
| /
2containerVCs---------
\_vcOne
Inside the viewWillAppear methods of vcZero and vcOne I have some print statements.
The problem is when the parentVC appears on scene and selectedSegmentIndex = 0 shows, it's print statement runs, but the print statement that is inside vcOne also runs too. Considering vcOne isn't on scene it's code shouldn't run.
I understand that when the parentVC loads both containerViews are loaded into memory. I tried these 2 SO answers but neither prevented vcOne's print statements from printing.
link
#IBOutlet weak var segmentedControl: UISegmentedControl!
#IBOutlet weak var vcZeroContainer: UIView!
#IBOutlet weak var vcOneContainer: UIView!
let viewControllerIdentifiers = ["vcZeroContainer", "vcOneContainer"]
#IBAction func segmentChanged(sender: UISegmentedControl) {
var newController = storyboard?.instantiateViewControllerWithIdentifier(viewControllerIdentifiers[sender.selectedSegmentIndex]) as UIViewController
let oldController = childViewControllers.last as UIViewController
oldController.willMoveToParentViewController(nil)
addChildViewController(newController)
newController.view.frame = oldController.view.frame
transitionFromViewController(oldController, toViewController: newController, duration: 0.25, options: .TransitionCrossDissolve, animations:{ () -> Void in
// nothing needed here
}, completion: { (finished) -> Void in
oldController.removeFromParentViewController()
newController.didMoveToParentViewController(self)
})
}
and
link
#IBAction func segmentChanged(sender: UISegmentedControl) {
switch segmentedControl.selectedSegmentIndex
{
case 0:
vcOneContainer?.removeFromSuperview()
vcOneContainer = nil
case 1:
vcZeroContainer?.removeFromSuperview()
vcZeroContainer = nil
default:
break;
}
}
How to I remove vcOneContainer from memory when selectedSegmentIndex = 0 is showing?

Swift Objects in different class not updating

I need the stepper and label to reset back to 0 at the same time that my variables reset. The problem is the steppers and labels are in a different class and are not resetting when the variables do. I tried using delegates(if someone can show me the best way that would be great) instead of an instance of my view controller, but I can't get anything to work. Thanks for any help in advance.
ViewController:
class ViewController: UIViewController
{
var colors = CircleView()
#IBOutlet weak var circleView1: CircleView!
#IBOutlet weak var blueStepper: UIStepper!
#IBOutlet weak var greenStepper: UIStepper!
#IBOutlet weak var redStepper: UIStepper!
#IBAction func stepperChange(sender: UIStepper)
{
circleView1.redd1 = Int(redStepper.value);
redValue.text = Int(sender.value).description;
}
#IBAction func stepperChange1(sender: UIStepper)
{
circleView1.greenn1 = Int(greenStepper.value);
greenValue.text = Int(sender.value).description;
}
#IBAction func stepperChange2(sender: UIStepper)
{
circleView1.bluee1 = Int(blueStepper.value);
blueValue.text = Int(sender.value).description;
}
}
UIView:
class CircleView: UIView
{
var colors1=ViewController()
func updateStepper
{
if(redd1==Int(red1)&&greenn1==Int(green1)&&bluee1==Int(blue1))
{
redd1=0;
greenn1=0;
bluee1=0;
colors1.redStepper.value=0.0;//
colors1.greenStepper.value=0.0;//
colors1.blueStepper.value=0.0;//
}
}
}
I do not quite understand your code, like the "if" condition in your CircleView, the lack of parameters to the method "updateStepper". I am assuming you just wrote some "swift-pseucode" and I will ignore some parts of it to explain how you could implement a delegate for it. Below is an example code:
import UIKit
protocol CircleViewDelegate: class {
func updateStepper(view: CircleView)
}
class ViewController: UIViewController, CircleViewDelegate{
#IBOutlet weak var circleView1: CircleView!
#IBOutlet weak var blueStepper: UIStepper!
#IBOutlet weak var greenStepper: UIStepper!
#IBOutlet weak var redStepper: UIStepper!
var circleViewDelegate: CircleView!
override func viewDidLoad() {
super.viewDidLoad()
circleViewDelegate = circleView1
circleViewDelegate!.delegate = self
}
func updateStepper(view: CircleView) {
//code you want to execute when you call updateStepper() in the CircleView()
}
}
class CircleView: UIView {
weak var delegate: CircleViewDelegate?
func updateStepper() {
//whenever you want your viewController to updated other views based
//on a condition inside an element like UIView, you can use a delegate
//this way, your code is executed by the ViewController whenever you want
delegate?.updateStepper(self)
}
}
A callback in your UIView must be set to call "updateStepper" when you want. Unfortunately, I didn't quite understand the time it should be called according to your question.
I hope this helps!
Have you tried NSNotification?
If it's always going to reset to zero, then create a func without the if statement in CircleView:
func resetStepper(not: NSNotification) {
r1 = 0
g1 = 0
b1 = 0
c1.rStep.value = 0.0
c1.bStep.value = 0.0
c1.gStep.value = 0.0
}
Also in CircleView's createView func, add:
NSNotificationCenter.defaultCenter().addObserver(self, selector: "resetStepper:", name: "ResetStepper", object: nil)
Then in the view controller, post a notification from whichever button is calling it.
#IBAction func callReset(sender: AnyObject) {
NSNotificationCenter.defaultCenter().postNotificationName("ResetStepper", anObject: nil)
}
That will send the notification that CircleView is listening for to call the function.
Hope that works for you.

Swift objects won't update after delegate called

I want a stepper and label to reset to zero after my variable in another class is also reset. The variables reset but the stepper and label do not even after using a delegate.
View Controller:
class ViewController: UIViewController, CircleViewDelegate {
var colors = CircleView()
#IBOutlet weak var circleView1: CircleView!
#IBOutlet weak var redStepper: UIStepper!
#IBOutlet weak var redValue: UILabel!
#IBAction func stepperChange(sender: UIStepper)
{
circleView1.redd1 = Int(redStepper.value);
redValue.text = Int(sender.value).description;
}
func updateRedStepperValue(value: Double) {
redStepper.value = value
redValue.text = Int(colors.redd1.value).description;
}
override func viewDidLoad() {
super.viewDidLoad()
colors.delegate = self
}
}
CircleView:
protocol CircleViewDelegate
{
func updateRedStepperValue(value: Double)
func updateGreenStepperValue(value: Double)
func updateBlueStepperValue(value: Double)
}
class CircleView: UIView
{
var delegate: CircleViewDelegate?
var redd1 = 0
func updateValues()
{
if(redd1==Int(red1))
{
redd1=0;
delegate?.updateRedStepperValue(0.0)//
}
}
}
The problem is that your making a brand new instance of your CircleView.
let cycle = CircleView()
You need to set your delegate to your current working instance.
To do so, you should replace your assignment in your viewDidLoad with the following:
override func viewDidLoad() {
super.viewDidLoad()
let app = UIApplication.sharedApplication().delegate! as! AppDelegate
if let viewControllers = app.window?.rootViewController?.childViewControllers {
viewControllers.forEach { vc in
if let cont = vc as? CircleView {
cont.delegate = self
}
}
}
}
Here's an article with project files.

Weird Button Animation

It's my first try on IOS animation, so if I'm worry from the very beginning, just tell me the right direction.
All I want: when I click ButtonOne, Label disappears slowly.
The code as below:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var labelHeight: NSLayoutConstraint!
private var isHidden: Bool = false
#IBAction func clickButtonOne(sender: UIButton) {
isHidden = !isHidden
if isHidden {
labelHeight.constant = 0
} else {
labelHeight.constant = 60
}
UIView.animateWithDuration(1.0, animations: {
() -> Void in
self.view.layoutIfNeeded()
}, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}
Before I click ButtonOne:
After I click ButtonOne(label shrinks from bottom to top):
The UILabel is disappearing, but it's content is still visible.
You need to set the clipsToBounds property of the UILabel to true.
label.clipsToBounds = true
You can set the same property in the interface builder by checking the Clip Subviews property in the attributes inspector.
I think you should also animate UIView.alpha property:
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var button: UIButton!
#IBOutlet weak var labelHeight: NSLayoutConstraint!
private var isHidden: Bool = false
#IBAction func clickButtonOne(sender: UIButton) {
isHidden = !isHidden
var alpha: CGFloat = 1
if isHidden {
alpha = 0
labelHeight.constant = 0
} else {
labelHeight.constant = 60
}
UIView.animateWithDuration(1.0, animations: {
() -> Void in
self.button.alpha = alpha
self.view.layoutIfNeeded()
}, completion: nil)
}
override func viewDidLoad() {
super.viewDidLoad()
}
}

Resources