Load UIView from Nib with his subviews in MonoTouch - ios

currently i am loading View that has some subviews
with the
NSBundle.MainBundle.LoadNib("NibName", this, null) function
but than i manually add the subviews of the loaded view with the
this.AddSubviews(this.subview1).
how can i load the view from the Nib so i wont need to manually add the subviews to the current view?
EDIT:
now i tried to get the result of the LoadNib function :
var res = NSBundle.MainBundle.LoadNib("ViewX",this,null);
var betterRes = Runtime.GetNSObject(res.ValueAt(0)) as Viewx;
now "this" has the properties of the sub elements initialized but his view is empty.
and "betterRes" has all the subviews in the view but all the properties of the sub elements are null.
just to clarify ... each sub element is button or label and has is own view.

If I understand correctly what do you want: load the view with outlet or action from nib file to main view, here is a try:
//Load the view
var res = NSBundle.MainBundle.LoadNib("ViewX",this,null);
// init your view with IntPtr
var betterRes = new Viewx(res.ValueAt(0));
//then use this view as main view
this.View = betterRes; //Or add subview: this.View.AddSubView(betterRes);
Now some properties in your view should work. Hope this help!

Related

Add a custom view to the UIViewController from the custom view class

I have a custom view. I named AnimatingView. I have customized the view in the AnimatingView.swift. In the ViewController, I am initiating the view with
let customAnimatingView = AnimatingView(overView: self.view)
and then I add the subView with -
self.view.addSubview(customAnimatingView)
However, I don't want the user add it as a subView like above, rather. I want to call a func from AnimatingView and the custom view should add it the controller like -
customAnimatingView.preset()
Can anyone give me some hint on how can I achieve such behavior.
Inside the custom view do
// add a property that refers to the the vc container of the view
// init it when you create an instance of the view
weak var parentController:UIViewController?
func present() {
parentController?.view.addSubview(self)
}
OR if you need to send the main view instead
var parentView:UIView?
func present() {
parentView?.addSubview(self)
}

Trouble while declaring an element of view in its class file

I've a view controller which contains a view element like the following (the view is the orange element) :
The view is associated to a custom view class that I called "Quickie.swift". This view is an object with a textfield and a button so I want to declare both in the Quickie.swift.
However I can drag/drop to create declaration in the swift file :
And here nothing happen.
I can't find out how to declare this variable in my view object.
Did you tried to write it by your own and drag it to the code?
#IBOutlet var view: UIView!
You Need to release r-Click on view: UIView!

Short lag when setting label text using storyboards

In my application, I have a mainViewController with some content on it. At some points, I load an overlay view controller from storyboard. The overlay view controller is smaller than the screen and is presented on top of the mainViewController. I initialize it the following way:
class MyOverlayViewController {
#IBOutlet var textLabel: UILabel!
#IBOutlet var countLabel: UILabel!
static let storyboard = UIStoryboard(name: "...", bundle: nil)
// Return a new view controller
class func newViewControllerWithData(data: AnyObject) -> UIViewController {
let vc = storyboard.instantiateViewControllerWithIdentifier("MyOverlayViewController") as! MyOverlayViewController
Timing.performAfterDelay(0) {
vc.titleLabel.text = data[...] // Load title label text
vc.countLabel.text = data[...] // Load count label text
}
return vc
}
}
I cannot set the text of the labels immediately in the method newViewControllerWithData, because that produces the following error: fatal error: unexpectedly found nil while unwrapping an Optional value. So the labels are nil when accessing them immediately in this method.
It seems like the two label outlets are not loaded immediately when the view controller is instantiated from storyboard, because this takes a (very) short time.
Therefore, I use my method Timing.performAfterDelay(0) which executes the code after the next run-loop cycle (it starts a timer with duration 0 and executes the code as callback). The code is (I have checked that) executed on the main thread.
The problem is the following:
Sometimes (not always, and not reproducible!), when loading the overlay view controller, for a fraction of a second the labels are empty (like I have defined them in storyboard) before they are showing the text.
So the user sees empty labels for a short moment before the actual data is loaded into the labels.
How can I fix this behavior?
Is it possible somehow to access the outlets immediately after instantiating the view controller from storyboard, without using Timing.performAfterDelay(0)?
Help would be appreciated.
Outlets are set after view is loaded i.e. when viewDidLoad gets called on the view controller. However, calling it directly like vc.viewDidLoad() will not work, you have to access the view controller's view like let dummyVariable = vc.view instead. Here's the code that force loads the view and then sets the label values.
class func newViewControllerWithData(data: AnyObject) -> UIViewController {
let vc = storyboard.instantiateViewControllerWithIdentifier("MyOverlayViewController") as! MyOverlayViewController
let _ = vc.view // force load the view
// now set your outlets as you please
vc.titleLabel.text = data[...] // Load title label text
vc.countLabel.text = data[...] // Load count label text
return vc
}
NOTE: This is not really a good practice though. MyOverlayViewController should be responsible for setting its label values instead of these being set from the outside. You could pass it the required data via a property or argument to a method, etc.

How to use a predefined view (nib) in a UITableViewCell?

My list consists of card views with an image and some text fields, all of which have a complex layout. This card is to be reused in the detail view, so containing it inside a UITableViewCell layout and then calling UITableView.registerNib() doesn't seem to work for me. I'd like to know the cleanest way to reuse the view I created in the NIB-file as both a list item and a part of my detail screen, while keeping as much of the view logic such as constraints and style in the NIB-file.
I'd like to know the cleanest way to reuse the view I created in the NIB-file as both a list item and a part of my detail screen
Do exactly what you're already doing: Use a nib (a .xib file) containing just one view, the UITableViewCell as designed, and register that nib with the table view - exactly the thing you say "doesn't seem to work for you". It does work. So now all your table rows consist of copies of this table view cell.
But there's the trick. When you want to show the view elsewhere, load the nib manually, pull out the view (the UITableViewCell), pull out its contentView, and add it as a subview to your interface.
// substitute correct name of xib file here
let arr = UINib(nibName: "MyTableViewCell", bundle: nil).instantiateWithOwner(
nil, options: nil)
let tvc = arr[0] as! UITableViewCell
let v = tvc.contentView // now it's a normal view! customize as needed
v.frame.origin = CGPointMake(100,100) // or whatever
self.view.addSubview(v) // and plop it into the interface! voilĂ !

How to inject viewcontrollers in viewcontrollers in swift ? To have a fixed top menu

Here is a draft of what I would like to do :
I would like to have a main container, which will be used to trigger Menu from everywhere.
I try to do this thanks to view.addSubview and addChildViewController.
But the second view disables the first one. It simply goes over.
How could I do to keep both functionalities ?
UPDATE:
I found a way that works, but it seems dirty :
I just move down the secondView frame according to the menu height, here is the code :
var test = mainStoryboard.instantiateViewControllerWithIdentifier("TestViewController") as TestViewController
var test2 = mainStoryboard.instantiateViewControllerWithIdentifier("Test2ViewController") as Test2ViewController
//proposeOrChooseViewController.delegate = self
view.addSubview(test.view)
addChildViewController(test)
test2.view.frame = CGRectMake(0, 60, test2.view.frame.size.width, test2.view.frame.size.height)
view.addSubview(test2.view)
addChildViewController(test2)
Is the frame of second view controller's view set correctly? Visually you can test it by setting a background color of view.
Also you might want to explore the Container View in storyboard. Container View lets you add a View Controller as child of another view controller.

Resources