Container views with segmented control in swift - ios

I have a segmented control with three segments. "Cattle", "Sheep" and "Goats". In Sheep and Goats there is another segmented control "RFID" and "Mobs"
I have used three container views on a parent viewController, a cattleView, sheepGoatMob view and a sheepGoatRFID view which have UITableViewControllers CattleTableViewController, SheepGoatMobTableViewController and SheepGoatRfidTableViewController. The parent view contains the if statement to hide/show each view, which works okay..
The problem that I am having is that each child view needs to be able to send the info on their pages to a soap web service from a UIBarButtonItem on the parent view. My first thought was to have a "send" button in each child view but because all three views are loaded into memory when the app starts, the button doesn't know which view function to call.
EDIT : How can I accomplish setting a button in each of the three views for the UIBarButtonItem of the parent viewController and allowing the correct function from the childViewControllers to be called?
Option 2: How could I access the three childviewcontroller's function through a UIBarButtonItem on the parent viewcontroller?

I found a solution to have all three views loaded into memory and be able to change which function I am calling using #Julian's response: Objective-c: How to invoke method in container view controller
//Determine which view is showing and point to the correct child class
func sendTransactionButton(sender: UIBarButtonItem) {
log.debug("send transaction button called p2p")
for childViewController in self.childViewControllers {
if childViewController.isKindOfClass(CattleTableViewController) && containerTableViewCattle.hidden == false {
var cattleVC = childViewController as! CattleTableViewController
cattleVC.transactions()
} else if childViewController.isKindOfClass(SheepGoatRfidTableViewController) && containerSheepGoatsRfid.hidden == false {
var sheepGoatRFIDVC = childViewController as! SheepGoatRfidTableViewController
sheepGoatRFIDVC.transactions()
} else if childViewController.isKindOfClass(SheepGoatTableViewController) && containerTableViewSheepGoats.hidden == false {
var sheepGoatsMob = childViewController as! SheepGoatTableViewController
sheepGoatsMob.transactions()
}
}
}
You need to ensure that your other views are hidden or you will get a warning from xcode.

Related

UIView container disappears after adding child view controller

I have a tab bar controller that has two tabs. One is a regular UIViewController and the other is a navigation controller. The navigation controller, I am able to push another view controller on it with a custom inputContainerView with no problems. But when I put a navigationViewController (name from mapbox) on the first tab as a child view, the custom inputContainerView no longer shows up. Even after I remove the child view controller from the first tab.
Adding child to tab 1
...
addChild(navigationViewController)
navigationViewController.view.frame = view.bounds
view.addSubview(navigationViewController.view)
navigationViewController.didMove(toParent: self)
}
func navigationViewControllerDidDismiss(_ navigationViewController: NavigationViewController, byCanceling canceled: Bool) {
navigationViewController.willMove(toParent: nil)
navigationViewController.view.removeFromSuperview()
navigationViewController.removeFromParent()
}
tab 2
override var inputAccessoryView: UIView? {
get { return inputContainerView }
}
override var canBecomeFirstResponder: Bool { return true }
The sequence I am trying to achieve is to add a child view controller to the first tab (navigationViewController which is named this from mapbox) click on the second tab and push a ui view controller on with the inputContainerView showing up. It shows up fine before I add the child view on the first tab but disappears after that
this is what the documentation says:
This method creates a parent-child relationship between the current view controller and the object in the childController parameter. This relationship is necessary when embedding the child view controller’s view into the current view controller’s content. If the new child view controller is already the child of a container view controller, it is removed from that container before being added.
Check the Highlighted part.

How to hide child view from parent view after some delay

hide child view after few seconds
I set time for that but i cant access child viewcontroller in my timer function
I tried dissmiss , removefromparent about not worked.
only self.view.isHidden = true is worked
I can't place it in timer
My Parent view
Child View:
Button code:
Timer code:
In Like_btn_Action() function, you:
create an instance of LikeViewController
add it as a child view controller
add its view to your view
set that view's background color
and then the function exits. At this point, you no longer have a reference to your instance of LikeViewController ... likeVC has gone out of scope.
You need to use a class-level var to maintain the reference to the loaded child view controller, along these lines:
var likeVC: LikeViewController?
#IBAction func Like_btn_Action(_ sender: Any) {
likeVC = self.storyboard?.instantiateViewController( etc ...)
}
Then, when you want to remove the view you added, you can "get to it" via:
likeVC.view.removeFromSuperview()
for example.

iOS - How to use a small view in different view controllers in Swift

I have a progress bar (with its own controller). This bar is supposed to be shown in different views depending on which view is visible. As the progress will be same, If possible I don't want to create many progress bar in many views rather I want to use same instance in all these views. Also in that way when I need to change any property of the progress bar it will be reflected commonly, which is required.
Please suggest me how can I use this common view. And also if my strategy is wrong, what would be the better design for such scenarios.
1) Well you have 2 options. You can declare a new Class ViewBox (or whatever name) and then use that inside your code
First View Controller
var box:ViewBox = ViewBox()
When you segue or transition to your next screen, you can have a predefined variable var box:ViewBox!. Then say when you press a button, the button has a function called transition.
//Now setup the transition inside the Storyboard and name the identifier "toThirdViewController"
override func prepareForSegue(segue:UIStoryboardSegue, sender:AnyObject?) {
if(segue.identifier == "toThirdViewController") {
var vc = segue.destinationViewController as! `nextViewController` //The class of your next viewcontroller goes here
vc.box = self.box
}
//Since The SecondViewController doesn't need ViewBox, we don't need it there.
}
where
nextViewController:UIViewController {
var box:ViewBox!
}
Or you could do a much simpler way and that is to look up a UIPageViewController :)

Why does initializing a view controller with nibName not set the new instance as file owner?

I am trying to display one view or another view inside the detail view of a master/detail based on a conditional.
These views will contain outlets and elements, so I would like to have view controllers for each that I can play with.
So I created a new UIViewController called AddPhotoViewController. This is how I add AddPhotoViewController.xib inside DetailViewController:
let photoVC = AddPhotoViewController(nibName: "AddPhotoViewController", bundle: nil)
let photoView = photoVC.view
photoVC.delegate = self
photoView.autoresizingMask = UIViewAutoresizing.FlexibleWidth
photoView.frame = area.bounds
area.addSubview(photoView)
The view loads properly in the detail view and looks like this:
AddPhotoViewController.xib's owner class has been set as well here:
When I tap the button, though the action is set properly in AddPhotoViewController to print a message, Xcode crashes.
Am I doing this correctly? Is there a more common practice for loading view X or view Y inside a view controller depending on user data?
Button action:
#IBAction func ButtonPressed(sender: AnyObject) {
println("worked!")
}
Button connection:
Console output:
I think you need to add the viewController:
addChildViewController(PhotoVC)
//and then
PhotoVC.didMoveToParentViewController(self)

UIButton across all pages of UIPageViewController

I am working on an iPhone app, and created a UIPageViewController (lets call it the container), which contains a number of UIViewController pages (lets call them the subpages). The subpages transition style is scroll.
Now, what I like to do is create a button on the top right corner of the container and NOT in the subpages. The idea is, the button will stay on screen when the subpages scroll from one page to the other. If I create the button in one of the subpages, then each subpage will have its own button, and the button will scroll with the subpages. I want to keep the button without moving in the container, while the subpages scroll.
I tried to add the button using the storyboard to the container, but it is now allowed in. I cannot drop it there, and I suspect the reason is because container is of type UIPageViewController.
How can I do that using the storyboard?
Thanks.
In your storyboard, create a standard Viewcontroller scene.
To this scene add your fixed buttons and a container view.
Adding the container view will automatically add an embedded view controller. Select this and delete it.
Drag a Page view controller into the storyboard.
Select the container view and drag from the "viewDidLoad" item in its "triggered segues" list to the page view controller. Select "Embed" as the segue type.
In code, add the button to the uipageviewcontroller
Here is a solution using storyboard. You have to do some code, but it's minimal
Add a View to your Page View Controller View Hierarchy in your attributes inspector
Create a UIView Subclass that allows touches to pass through the view if the user is not interacting with a subview (otherwise the user will not be able to swipe between pages). Thanks to #john Stephen for his answer to this question.
class TouchThroughView: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
for subview in subviews {
if !subview.isHidden && subview.isUserInteractionEnabled && subview.point(inside: convert(point, to: subview), with: event) {
return true
}
}
return false
}
}
Create an outlet to this view in your PageViewController instance.
set translateAutoresizingMaskINtoConstraints= false
add the outlet as a subview to your PageViewController's root view
Add constraints positioning the outlet in the root view
Set the background of the view you added to the page view controller to clear (In interface builder).
You are done! Add your subviews and constraints to the view you added to your page view controller in storyboard.
Your PageViewControllerWill look like this:
class MyPageViewController: UIPageViewController {
// step 3
#IBOutlet var touchThroughView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// your regular page View Controller implementation
// step 4
stationaryView.translatesAutoresizingMaskIntoConstraints = false
// step 5
self.view.addSubview(touchThroughView)
// Step 6
touchThroughView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
touchThroughView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
touchThroughView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
touchThroughView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
}
}
Your Story board will look like this:
Drag and drop a button to your controller (UIPageViewController) (make sure it is the good controller). And add some constraint to block it at the top corner.

Resources