how to move profile picture to a navigation bar when scrolling up? - swift

I have created this layout using UITableView header and I'm trying to move profile picture when scrolling up and removing full name and Phone number. First screen UI is what I have created and it is made in tableview header and
I want to achieve a functionality of a second screen when scrolling up.

You need add UIScrollViewDelegate to your tableView.
Table view inherit UIScrollView and their UIScrollViewDelegate methods.
So... you need set like this:
Somewhere set delegate:
tableView.delegate = self
(I think you mb already implement this because you need to implement UITableViewDelegate methods)
and implement UIScrollViewDelegate method:
extension YourControllerOrAnotherDelegateClass: UIScrollViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
// use scrollView.contentOffset to calculate when you need to update navbar
}
}
inside this method you can get content offset of your scrollView and update nav bar when you needed.

Related

Swift Scroll down should make Bar Item disappear

I want that the Bar Button Item diappear when I scroll down. My problem is that I don't know how to detect the scroll? I have tried some code but nothing worked. For example:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
print("123")
}
(Don't work, I call the method in viewDidLoad())
Also I don't know where I have to call the method. In viewDidLoad(), viewDidAppear() or somewhere else? I am new in Swift, sorry.
Does anyone know the answer?
The thing is you are calling it from viewDidLoad, that gets called only once when the view is loaded. You need to place this scrollViewDidScroll
function separately, after viewDidLoad for example, but not inside of it.
Also make sure you implemented UIScrollViewDelegate in your file. Then you can add scrollViewDidScroll method to detect when is the view scrolled and print('123') inside of it.
Also make sure to set your scrollView.delegate = self in your viewDidLoad.

how to get calculated frames in custom UIView with auto layout

I created a custom UIView based on a xib file and added some UIVIews with constraints.
In my View Controller I added a UIView and set the class to my custom view. So far so good. My custom View is displayed properly.
But now I do have a #IBInspectable (numerOfButtons: Int) and based on this number I want to add UIButtons programmatically to my custom view.
My problem is now, that I want to align this buttons to a subview in my custom view. So I try to set my button frames programmatically. But when I do this in layoutSubviews() my subviews are not calculated based of my auto layout constraints. I tried to call setNeedsLayout() and layoutIfNeeded() of my subview but this does not work.
How can I get the correct frames of my subviews (with calculation of my constraints) to work with them in layoutSubviews()
Or what do I wrong?
By the way. It seems that my approach does not works only if I try to run with iPad Pro 9.7 inch simulator?!
To set constraint programmatically will be time consuming thing but luckily we have an alternative solution with this library very easy to set constraint
let box = UIView()
self.view.addSubview(box)
box.snp.makeConstraints { (make) -> Void in
make.width.height.equalTo(50)
make.center.equalTo(self.view)
}
Hope this will help you

Image in ScrollView not being scrollable

I was asked to help out in a project with swift and work in xcode on a short timescale, neither which I have worked with before.
The task is getting a picture to be "zoomable". And after some researched I found that putting a UIScrollView on top of the image will suffice. Now, since the image view already exists and is integrated in the code on a level I do not dare triffle with, with some constraits and what not.
I dont want to start the process all over with a new image view and later try to hook it into the code. Mostly because the image view is inside a table cell inside of a table view.
What I have done is:
On the storyboard
Put the image view inside the view on the storyboard.
Assigned the delegate of the scroll view to the table cell.
I couldnt quite figure out how to constraint these so I mostly use 'Add missing constraints'.
In code for the TableViewCell
Inherited the UIScrollViewDelegate
made a new var with #IBOutlet weak var scrollView: UIScrollView!
Since I am in a controller, i cannot override viewDidLoad function, so I implemented that and set minimum and maximumZoomScale to some values.
Implemented a viewForZooming function that returns the UIImageView
I figured out somewhat how I can use the constraints and properties of the ImageView to resize and stuff, but the regardless of what I try to do, I cannot get the "zoom" to work.
Is there any property that the ImageView could have that is messing this up, what should I check for?
After reading and trying to figure out, what finally made it work was this:
The ScrollView was made parent in the Interface Builder to the ImageView
I magically made the constraints to fit the ScrollView aligned to everything around it mostly by Add missing constraints when prompted with constraint errors.
Rightclicked the ScrollView then for the delegate, clicked the + sign and dragged that to the UITableViewCell.
I also did the same for the Referencing Outlet
And code for the UITableViewCell is this:
class ClothesItemTableViewCell: UITableViewCell, UIScrollViewDelegate {
#IBOutlet weak var scrollView: UIScrollView!
var theImage: UIImage? {
set {
clothinhImageView.image = newValue
} get {
return clothingImageView.image
}
}
func viewForZooming(in scrollView: UIScrollView) -> UIView? {
return clothingImageView
}
}
Might not be perfectly clear, and I couldnt find the exact article that made the work done. But there are plenty that tries to solve this issue in different ways, and somehow this worked. Hopes it helpes somebody!

iOS: Add UIView to UITableView

I'm trying to add a UIView on top over the UITableView to mimic the iPhone Facebook style menu. I have it working fine by making the controller a UIViewController then adding a tableview however I am unable to make the menu a static menu unless the controller is a UITableView.
Is it possible to add a view ontop of a tableview and only make the tableview in the background scrollable without the view in the foreground scrolling?
Here is what I have with the subclass being UIViewController
But I am unable to make the tableview cells static via IB since it is not a subclass of UITableView Controller.
EDIT per NSJones Code:
It seems to be going somewhat in the right track. However the view still blocks the table. If I remove the view from the storyboard it will only display the table.
You can make a view hover the same way you make any real thing hover; Hold it up with something invisible.
Basically what you want to do is create a clear UIView (with user interaction disabled) that is the size of your view controller's view, and add it as a subview to your view controller's view property. That way it sits invisibly on top. then you can add a subview to that clear view and that subview won't move.
Edit:
It seems this nice clean approach won't work for you since you need your view controller to be a UITableViewController. The answer for this slightly more complex approach is to use a delegate method for UIScrollView which also works for UITableView. Apple has a fantastic demo of this concept in the WWDC2011 - Session 125 - UITableView Changes, Tips, Tricks video. If you can watch it I highly recommend it. The meat of this issue begins at about 36:10.
But to sum it up you implement the scrollViewDidScroll: delegate method. And handle the movement of the tableview by adjusting the position properties of the view. Here I am keeping an UIView property named viewToKeepStill still using this method.
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{
// CGFloat stillViewDesiredOriginY; declared ivar
CGRect tableBounds = self.tableView.bounds; // gets content offset
CGRect frameForStillView = self.viewToKeepStill.frame;
frameForStillView.origin.y = tableBounds.origin.y + stillViewDesiredOriginY; // offsets the rects y origin by the content offset
self.viewToKeepStill.frame = frameForStillView; // set the frame to the new calculation
}
Instead of adding it as a subview of the table view, add it as a subview of the superview of the table view; that way it won't scroll.
So instead of this:
[tableView addSubview:viewController.view];
Do this:
[tableView.superview addSubview:viewController.view];
Assuming you want something that is visible full-time with the table, start with a view which contains both the menu view and the UITableView. Make the table smaller so it ends where the menu view begins. The table view can work with less vertical space.
If you have your UIViewController's view to be your table view then your table is going to span over the whole screen, so you won't be able to add anything on top of it.
Why not try the following:
1) create a new UIViewController
2) add a view on top where you want your menu
3) in the space left under just drag a table view from the component library
4) don't forget to set the 2 table view delegates to be your view controller class
that's about it?

(iPhone/iOS) UISearchBar Scope Buttons cover first row of UITableView

I know this question has been asked before, but I have yet to find a true solution. I have a UITableView with a UISearchBar as its tableHeaderView. Whenever the scope buttons appear, they cover the first row of the UITableView.
I have tried using UITableView.contentOffset to offset the UITableView by the height of the scope buttons, and this works until the user taps the UITableView or scrolls it, at which point the UITableView jumps back to its original offset.
The best I've been able to do is set the UISearchBar as a separate item in the view, and simply resize the UITableView dynamically to show or hide it when the user taps a search button. The only problem is that there is no animation, so the transition is sharp.
UPDATE: I solved the problem by implementing a UISearchDisplayController, as this was the cleanest and easiest solution to work with. The UISearchDisplayController automatically shows/hides the scope buttons and moves the UITableView down accordingly. I didn't do this at first because I wanted the UITableView to remain visible rather than initially being blacked out by the UISearchDisplayController, however I've come to realize that the blackout does not hinder any functionality; the user would not have initiated a search if he wanted to continue looking at the UITableView the way it was.
Ideas:
Set the tableHeaderView to a UIView that has the UISearchBar as its subview, and resize that UIView when the scope buttons appear. The UITableView will hopefully respond to that view changing its frame.
Set the UISearchBar as the content of the first cell of the UITableView and use (void)reloadRowsAtIndexPaths:(NSArray *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation when the scope buttons hide or show. Return the proper height to have the cell animate to its new height.
Or you could use the method you describe (UISearchBar as a separate item in the view), and use an animation block to animate the transition so it's less sharp.
[UIView animateWithDuration:1.0 animations:^
{
//change table view frame here
}];
If you adjust the cell height of the header based on if the search controller is active or not, all works well
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
var headerHeight: CGFloat = 0.0
if searchController.isActive
{
headerHeight = searchController.searchBar.frame.size.height
}
return headerHeight
}