0

I add the subview inside the viewDidLoad method. And change its attributes in the viewDidAppear but don't success. Really don't know why, stucking for few hour for this stupid error??!

 var iv = InitView()
 override func viewDidLoad() {
        super.viewDidLoad()

        iv.frame = view.frame
        iv.hidden = true
        self.navigationController!.view.addSubview(iv)
}

And in the viewDidAppear

Every attribute of this view can't change or modife

iv.hidden = false ~> doesn't work

iv.label.text = "Test" ~> Update UILabel text doesn't work either

I don't want to put these code in the viewDidLoad because it will show the splashscreen longer as it takes.

Here is the code of InitView

class InitView:UIView {

    var indicator = Indicator()
    var label = UILabel()

    override init(frame: CGRect) {
        super.init(frame: frame)

        self.backgroundColor = UIColor.whiteColor()

        indicator.frame = self.frame
        indicator.autoresizingMask = [.FlexibleWidth,.FlexibleHeight]
        self.addSubview(indicator)
        self.indicator.Show()

        label.translatesAutoresizingMaskIntoConstraints = false
        label.textAlignment = .Center
        label.text = "Loading ..."
        if #available(iOS 8.2, *) {
            label.font = UIFont.systemFontOfSize(17, weight: UIFontWeightLight)
        } else {
            // Fallback on earlier versions
            label.font = UIFont.systemFontOfSize(17)
        }
        self.addSubview(label)

        var ac = [NSLayoutConstraint]()
        ac += NSLayoutConstraint.constraintsWithVisualFormat("H:|-0-[l]-0-|", options: [], metrics: nil, views: ["l":label])
        ac += NSLayoutConstraint.constraintsWithVisualFormat("V:[i]-10-[l(30)]", options: [], metrics: nil, views: ["l":label,"i":indicator.container])
        self.addConstraints(ac)

        //self.autoresizingMask = [.FlexibleWidth,.FlexibleHeight]
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}
TomSawyer
  • 3,711
  • 6
  • 44
  • 79
  • How do you have a navigation controller when the view loads? And why are you adding a view to its view directly? – Wain Jun 08 '16 at 18:04
  • I want to display loading view (iv) on top over of navigationController – TomSawyer Jun 08 '16 at 18:05
  • What is the background color of `iv`? – beyowulf Jun 08 '16 at 18:17
  • @beyowulf white, does it matter? I can't change text, show or hide it – TomSawyer Jun 08 '16 at 18:23
  • I'm guessing you didn't override `init()` but just `init(frame:CGRect)` which is the designated initializer for `UIView`. It is a best practice to use `init(frame:CGRect)` when creating views programmatically. `UIView` defaults to having a clear background color. My point was more try changing the background color and see what happens. – beyowulf Jun 08 '16 at 19:04
  • @beyowulf i already have `iv` override `init` here the init code of `iv` : `override init(frame: CGRect) { super.init(frame: frame)` . The trouble is i can change any attribute of this subview in `viewDidLoad` but can't do the same thing in `viewDidAppear` except remove it from superview – TomSawyer Jun 08 '16 at 19:17
  • You are calling `init()` but you overrode `init(frame:CGRect)`. There is a difference. Change `var iv = InitView()` to `var iv = InitView(frame:CGRectZero)` – beyowulf Jun 08 '16 at 19:40
  • @beyowulf i've tried your way, but didn't work. I don't think call init with frame make any sense. – TomSawyer Jun 08 '16 at 20:05
  • Have you tried changing the background color of `iv` in `viewDidAppear`? Have you tried inspecting the view hierarchy of `self.navigationController?.view`? Could you post your entire `InitView` class to your question? – beyowulf Jun 08 '16 at 20:19
  • @beyowulf i can do anything with `iv` in the `viewDidLoad` but can't do anything in `viewDidAppear` i've tried to change text and print the value in `viewDidAppear` and it prints the correct value but it don't show the updated result on the view. So i think in the `viewDidAppear` method, somehow it doesn't update the subviews ? :( . I don't know why. – TomSawyer Jun 08 '16 at 20:28
  • @beyowulf i understand what did you say, and i already change to `let iv = InitView(frame:CGRectZero)` to test and i sure with you the code in init method of `iv` subview has been executed. As i told you, i print the attributes and see it has been updated but didn't be represent on the view only on `viewDidAppear` but everything works fine in `viewDidLoad`, so i surely think the reason is not about the initliatization of `iv` – TomSawyer Jun 08 '16 at 20:51
  • What appears on the screen? Where are you adding `label` as a subview of `InitView`? What does that code look like? – beyowulf Jun 08 '16 at 20:54
  • I add the UILabel in the init method of iv, i already set one uilabel , and one subview, everything display fine with this default properties. But on the superview, i want to change `iv` properties / attributes depend on the context. And it didn't work in `viewDidAppear` – TomSawyer Jun 08 '16 at 21:05
  • Perhaps you could post the code? – beyowulf Jun 08 '16 at 21:14
  • @beyowulf i already updated the code of `iv` view – TomSawyer Jun 08 '16 at 21:16
  • Thanks. My bad. You were right, but all of the code you've posted works fine. Though, you don't have enough constraints to satisfy the auto layout engine. Your label didn't show up for me without adding more. – beyowulf Jun 08 '16 at 21:36
  • @beyowulf it doesn't matter. you can make the uilabel display by your way, i didn't post the code of the`indicator`, The constraint depends on the indicator position. You can remove it and center the UILabel and simply change the text, change the background or simpliest hide the view in the `viewDidAppear` and it didn't work! – TomSawyer Jun 08 '16 at 22:26
  • That's what I'm saying. I did all of that, and it does work. I can change its text or hide it or change its frame from `viewDidAppear` You might be losing a reference to it somehow but nothing in the code you've posted indicates what's wrong. – beyowulf Jun 08 '16 at 22:35
  • @beyowulf I've found the cause of this annoying error, because i insert `sleep(10)` right after the update label text. `iv.label.text = "tesst";sleep(10);` Why inserting this method will make unable to update UIView? – TomSawyer Jun 08 '16 at 23:05
  • @beyowulf do you know why any process take long time to execute will prevent changing view's properties in `viewDidAppear` ? – TomSawyer Jun 10 '16 at 09:46
  • Read Palle's answer [here](http://stackoverflow.com/questions/27517632/how-to-create-a-delay-in-swift) – beyowulf Jun 10 '16 at 12:23
  • @beyowulf Tks. But itsn't only the sleep method, any function take long time to process like a heavy sqlite query ... it will override the updating view command , this answer didn't explain that – TomSawyer Jun 10 '16 at 19:18
  • 1
    Sleep stops all threads. The UI operates on a run loop if you block the main thread that run loop stops. This is why you've updated properties on your UIViews, but those properties do not have a chance to get drawn to the screen. Doing something that is processor intensive on the main thread will have the same result. Either update the UI earlier in your view controller's life cycle so the UI run loop is completed before being blocked or dispatch processor intensive tasks to a background thread. – beyowulf Jun 10 '16 at 19:39
  • @beyowulf So, what am i supposed to do in this situation? I want to display loading view to wait until heavy task (not `sleep()`) has been finished to hide the loading view indicator. – TomSawyer Jun 12 '16 at 16:06
  • If it's not UI related you can dispatch to a background thread, do the task, dispatch to main thread, update the UI. You can do this using Grand Central Dispatch. See the first snippet [here](https://thatthinginswift.com/background-threads/) – beyowulf Jun 13 '16 at 16:17
  • So, nothing i can do if i want to interfere to the UI? :( – TomSawyer Jun 13 '16 at 20:44

0 Answers0