Using RealmSearchViewController with a UITableView - ios

I'm developing my first app in swift, which has a table that shows data stored using Realm. I've managed to add stuff to the Realm and show it in a table. Afterwards I wanted to add search capability and stumbled upon these two guides: http://www.raywenderlich.com/81615/introduction-to-realm and https://realm.io/news/building-an-ios-search-controller-in-swift/. I would like to use RealmSearchViewController, but I can’t seem to fit it to my setup. I tried using a UITableViewController embedded in a Navigation Controller, but I need a button at the bottom of the screen, where the user should tap to add an entry to the list. I tried using a tableFooterView with a button, but it can only stick to the bottom of the table and not the bottom of the screen. I also tried using a Tool Bar and a Tab Bar in the Navigation Controller, but it doesn’t show as the table takes up the whole screen.
What I would like to achieve is something like Airmail for iPhone, where there’s a Tab Bar at the bottom that is hidden when the user scrolls. Above the Tab Bar I’d like a table with content from the Realm, and then a Search Bar, which is directly below the Navigation Bar. I’d like to use RealmSearchViewController as it makes searching a lot easier, but how can I adapt it to be used with a Table View and not a Table View Controller?
Any other suggestions as to how I can achieve the same functionality?
Thanks!

My recommendation would be to create a parent view controller that arranges the the view of RealmSearchViewController so that it doesn't cover the entire screen, and then arrange a UIButton at the bottom.
You can do this in a Xib/Storyboard by arranging a view and a button with autolayout and then simply add the view from RealmSearchViewController as a subview to the view in this parent view controller.

Related

how to manage view controllers in a sequential pattern - swift

I'm trying to implement sth like images below. there are some views that should be displayed in a sequential order and a bar above them shows the flow of tasks.
as it is shown, first profile view should be displayed. when the user clicks on Go to Next View Button second view (price view) should be displayed. the top bar shows the current view where we are in it. I've tried PagingMenuController already to create a menu with views and then disable scrolling. but PagingMenuController loads all views at the same time and also i don't know how to go to next menu item within child views. now I'm thinking of a container view might be helpful but i didn't use container view so far and i don't know it's good for my purpose or not.
also i want that top bar without swiping between views (only on buttons) and one enable view at the same time.
any helps would be apprectiated.
Your question is both broad and vague. My answer is also going to be fairly high level. I suggest you follow my outline, and if you get stuck on a particular step, post your code, tell us about the problem you're having, and we can help you fix it.
This is pretty simple. Create custom view controller. Give it a container view at the bottom that would contain the current child view controller. Use view controller transition methods to switch between child view controllers. You'll want to add layout anchors to each new child view controllers to pin all of it's view's edges to the edges of the container view.
Create a custom control on top to show the dot and highlight the title of the current view controller.
If you want the next/previous buttons to be on the child view controllers, put them there, and add a delegate property to all the child view controllers that points to the parent view controller, with next and previous methods.
BTW, in languages, like English, where text is laid out from left to right, I would think your first page would be on the left and the last page would be on the right. (I think it makes more sense for profile to be on the left and pay on the right.)

Dynamically increase/decrease height of custom UINavigationBar

I followed this blog post that explains how you can implement a custom UINavigationBar that has an increased height, if for example you wanted to put additional ui elements in the nav bar underneath the rest of the bar content that will persist between navigation on the stack. This code works really well in the case where you always want it to be that increased height.
In my app, I need to start the navigation bar at its default height, then increase it later, adding more content, after the user performs a given action. Very similar to the song info and controls in the iTunes Store:
So I put some checks in place to not reposition anything if a BOOL property is NO. When I set it to YES, I call [self setNeedsDisplay] which will call layoutSubviews to position everything appropriately based on that boolean value. sizeThatFits is also called and I return the proper height.
The problem is, I can't call [self setTransform:CGAffineTransformMakeTranslation(0, -(NavigationBarHeightIncrease))]; in initialize. Instead I call that at the same time I change the boolean value to YES. Because of this, all of my elements are moved up that amount. But if I don't call setTransform, the elements in the nav bar are in the proper position, but the bar itself is positioned too far down, so that the custom view I've added to the bar is shown overtop the view controller's view - it bleeds out, and the extra space I added is black not the navigation bar's background color.
If I call setTransform in initialize, when the height is the default height, the elements are moved up when they shouldn't be.
So, how can I properly dynamically change the height and positioning of a UINavigationBar subclass?
As suggested in the comments, to achieve the behavior where a custom navigation bar (not subclassing the native control) persists across pushes and pops of controllers in a navigation controller, you'll need to have a single controller with the custom navigation bar and then a single embedded view that resolves to a UINavigationController with its view controllers underneath. Then, it will also be necessary to set the navigation controller's delegate to the root controller so that the title and other properties can be updated as the sub-controllers are pushed and popped. I've provided a screenshot below of what the storyboard version of this might look like:
An option is to create a UIViewController in storyboard which has only the control view you wish to show below the navigation bar with everything else transparent. The advantage here is you design this using the normal tools. Use constraints to place it just below the navigation bar and to set the heights, widths etc of your views.
When you wish to show the control, you can create an instance of this UIViewController and remove the content view from it and add it to the view hierarchy of what is on screen.
There are two options for inserting the extracted base view:
If you add this control view to the view controller at the top of
the navigation stack (what is on screen), it would be covered when
you push on a new controller. This is not what you said you wanted.
If you add this control view to self.navigationController.view, then
it will persist across pushes and pops. This is what you said you wanted.
I use this approach to provide popup help bubbles to describe what is on screen. Depending on whether I use option 1 or 2, I can persist help across multiple pushes/pops.
I got the idea from this tutorial which describes the general approach: http://blog.typpz.com/2013/12/09/ios-sdk-create-a-pop-up-window/
That link provides a full code example on how to bring up the view and remove the view.
This would let you design it in IB, present and dismiss it as required and persist it across navigation sequences.
Hope this helps.

Xcode 6 - Swift - Custom Tabbar with Navigation

I'm trying to create a tabbed application with navigation elements inside the tab bar, as seen in the picture below (the red bar) using Swift/XCode 6.2. Basically those three icons in the middle will direct the user to different view controllers. The other two icons would be context-based. For example, on a table view page you would see the menu icon and add new icon as seen in the image. However, clicking on a row would change the menu icon to a back icon, and the add icon to something else.
That's the general idea, but I'm having a very hard time implementing something even close to this. The first issue is that whenever I embed a view in a Tab Bar Controller, I can't move the tab bar to the top. However, when I create a custom UITabView in a View Controller, Control + Click and dragging a Tab Bar Item to another view doesn't create a segue. I haven't even begun to tackle having the navigation elements inside the bar.
I guess what I'm asking is just for a little guidance on what route to take to tackle this. I'm assuming I can't use a Tab Bar Controller or Navigation Controller because it doesn't seem like I can customize them all that much. So custom Tab Bar and Navigation Bars, and then implemnt the segues and button changes programmatically?
Thanks.
I will try to guide you from an architectural perspective (so you won't find much code below).
Using a UITabBarController
In order to achieve what you are suggesting, you are right you cannot use a UITabBarController straight away, among several reasons, the most immediate one is that they are meant to be always at the bottom and you want it in top (check Apple's docs). The good news is that probably you don't need it!
Note: If you still want to go with a UITabBarController for whatever reason, please see #Matt's answer.
Using a UINavigationController
You can use a UINavigationController to solve this task, since the UINavigationBar of a UINavigationController can be customized. There are multiple ways on how you can organize your view's hierarchy to achieve what you propose, but let me elaborate one option:
To customize a UINavigationBar's to add buttons, you just need to set its navigationItem's title view:
// Assuming viewWithTopButtons is a view containing the 3 top buttons
self.navigationItem.titleView = viewWithTopButtons
To add the burger menu functionality on a UINavigationController you can find several posts on how to do it and infinite frameworks you can use. Check this other SO Question for a more detailed answer (e.g. MMDrawerController, ECSlidingViewController to mention a couple).
About organizing your view hierarchy, it really depends on if when the user taps one of the main top buttons, it will always go to the first view controller in the new section or if you want to bring him back to the last view in the section where he was.
3.1 Switching sections displays the first view of the new section
Your app's UIWindow will have a single UINavigationController on top of the hierarchy. Then each of the 3 top buttons, when tapped, will change the root view controller of the UINavigationController.
Then, when the user changes section, the current navigation hierarchy is discarded by setting the new section view controller as the UINavigationController root view controller.
self.navigationController = [sectionFirstViewController]
3.2 Switching sections displays the last displayed view in the new section
This will require a slightly modified version of the above, where your each of your sections will have its own UINavigationController, so you can always keep a navigation hierarchy per section.
Then, when the user taps one of the top buttons to switch section, instead of changing as previously described, you will change the UIWindowroot view controller to the new section's UINavigationController.
window.rootViewController = sectionNavigationController
Using a custom implementation
Of course, the last and also very valid option would be that you implement yourself your own component to achieve your requirements. This is probably the option requiring the biggest effort in exchange of the highest customizability.
Choosing this option is definitely not recommend to less experienced developers.
I'd like to take a stab at this--I think it is possible to use a tab bar controller here.
Your topmost-level view controller will be a UITabBarController with a hidden UITabBar.
Each tab is contained in a UINavigationController.
All view controllers in the navigation controller will be a subclass of a view controller (say, SwitchableViewController).
In SwitchableViewController's viewDidLoad, you set the navigation item's title view (i.e. whatever's at the center; self.navigationItem.titleView) to be the view that holds the three center buttons. Could be a UISegmentedControl, or a custom view.
Whenever you tap on any of the buttons, you change the topmost UITabBarController's selected index to the view controller you want to show.
Issues you may encounter:
Table views inside tabs will have a scrollIndicatorOffset at the bottom even if the tab bar is hidden.
Solution: Play around with the automaticallyAdjustsScrollViewInsets of the tab bar controller, or the inner view controller. https://stackoverflow.com/a/29264073/855680
Your title view will be animated every time you push a new view controller in the navigation stack.
Solution: Take a look at creating a custom transition animation for the UINavigationController.

Designing view on top of multiple embed views

I have the task to design a application that has a main view which is always visible (it has a button on it's bottom side, and when pressed a image displays on top of all views), and a set of TableControllerView's that should appear under it, and the user needs to be able to navigate through them.
I know that you can embed a view inside another, but you cannot refer more than one view to it. The current way I'm trying to do now load one TableViewController inside the embed view, and when the user clicks the cell I manually load the other controller and add it as a child of the main view, which is the RootViewController. The problem with this approach is that the navigation bar gets stuck using the root view controller, so I have to manipulate the main navigation items on each subview transition, and second is that the frame for the second view I load is coming as it had full size, making some cells be under the main view button. This way doesn't uses segues for transition, so it makes the storyboard kinda useless.
I was thinking into using a TabViewController with it's tab hidden, but wanted to ask here for a better solution.
As you discovered, a TableViewController likes to fill up the whole screen (except navigation bars, tab bars, status bar, etc. which are official Cocoa Touch GUIs). When you want a table view to fill only part of the screen, you are supposed to use a UITableView but not a UITableViewController. You set your custom view controller object (subclass of UIViewController, not UITableViewController) as the table view delegate and data source. You will need to duplicate part of the functionality of UITableViewController in your custom view controller, but it's not a lot more than you have to do already to supply the data.
You should probably follow the standard design pattern and have separate view controller objects for each of the "pages" the user can navigate to. You just have a main button and image on each of them. But I could imagine why that might not give you exactly the effect you want.

Persistent header in app with UINavigationController

I have a nice iPhone app built that uses a UINavigationController to navigate through a series of tableviews. I now want to add a persistent banner at the top of all of my views, either above the navigation bar or just below it. I do not want it to scroll with the tableview, so I do not want to make it a custom first row.
Any ideas on the best way to approach this?
What I did to achieve this was to make a new UIView for each of the views that I needed the banner on, and placed the banner in there, and the table or other view below the banner. This doesn't keep the banner there persistently through the transitions which is what I really wanted, but I was able to get a non-scrolling header above my tables.
EDIT:
The "correct" way to do this now would be to have a root view controller that consists of your header, and a container view, and then all of the navigation and content goes inside your container view. Although this does require ios6+
You could customize your navigation bar so that it displays the "classical" bar and then, above or below it, it draws your specific content. See this post for more detail.

Resources