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.
Related
I'm using EasyTipView to create a custom tip view have a button inside look like the image below. But notthing happen when I click to button inside tip view. Does anyone have use this libray and know how to fix this problem ?
My demo: github.com/minhtien1403/TestTipView
Library link: https://github.com/teodorpatras/EasyTipView
View hierarchy is fine, nothing overlay the button
As from your github demo, I notice things make button click inside not working.
First of all, in your CustomTipView when ever you change to position, you call translatesAutoresizingMaskIntoConstraints to redefine view which make the xib not working correctly anymore. Just need to remove this
fileprivate func arrange(withinSuperview superview: UIView) {
// your others code
if case .view(let contentView) = content {
contentView.translatesAutoresizingMaskIntoConstraints = false // remove this
contentView.frame = getContentRect(from: getBubbleFrame())
}
// your others code
}
I have added a UI Button inside of a stack view which is inside of a table view in my storyboard. When I click on my button the correct output is printed in my debugger console but there is no indication in the app that the button has been clicked (no default animation). I have tried looking at my view hierarchy and changing all of the parent views to clip to bounds. Any idea why the button is functioning but not being animated to the user?
The quick fix to your problem is to set delaysContentTouches = false for your table view.
According to the Apple Docs,
If the value of this property is true, the scroll view delays handling the touch-down gesture until it can determine if scrolling is the intent. If the value is false, the scroll view immediately calls touchesShouldBegin(_:with:in:). The default value is true.
See the class description for a fuller discussion.
Alternatively, if you have subclassed the UIScrollView, you can get the same thing done by overriding the following function,
class MyScrollView: UIScrollView {
override func touchesShouldCancel(in view: UIView) -> Bool {
return type(of: view) == UIButton.self
}
}
If I am using UITabBarController Item1 and Item2 viewControllers are displayed properly. But UITabBarButtonItem is not displaying item1's redirect page. UITabBarButtonItem must display on all pages .
My problem is UITabBarButtonItem is does not display the childViewController(red page). How to display the UITabBarButtonItem to childViewController?
Firstly, you should embed the first view controller in the hierarchy (the blue view controller) in a navigation controller. Then, in the red view controller, make sure that hidesBottomBarWhenPushed property is set to false:
// for instance, let's assume that you will do it in the `viewDidLoad()`:
override func viewDidLoad() {
super.viewDidLoad()
hidesBottomBarWhenPushed = false
// ...
}
Or if you want to achieve from the interface builder, select the red view controller and from the attribute inspector and make sure that the "Hide Bottom Bar on Push" option is unchecked:
Otherwise, if there is no navigation controller (presenting instead of pushing), there is no way to display the bottom bar in the red view controller.
I have two UIViewControllers, When I click on a button of first UIViewController then tableView(Of Second UIViewController) should open, and when I click on another button of First UIViewController then Collection view(Of Second UIViewController) should open.
I mean When Table View will open Collection view will be hidden and Vice versa, both I want in a single View controller.
In image you can see that TableView open with images, but when I will click on first cell the collection view should open in same layout.I mean it has to show like this.
I am new in UI.
So How can I implement the UI.
Thanks.
Thanks for asking question.
I am assuming you are doing in this way:
First put a global Bool Variable called: flagIsShowTableView
Now on your FirstViewController when you click on buttonTable for table:
you have to set Bool: flagIsShowTableView = true
Now when you click on buttonCollection:
you have to set Bool: flagIsShowTableView = false
Now on SecondViewController:
in ViewWillAppear: you have to manage in this way:
if(flagIsShowTableView) {
tblView.hidden = false
colView.hidden = true
} else {
colView.hidden = false
tblView.hidden = true
}
I am sure that you have set and manage all the delegate and datasources methods.
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.