Closed acegreen closed 8 years ago
What I'd do is add another view to the containing ViewController and manage its position similarly to the header view. I've just commited an example implementation here: https://github.com/spro/TwitterProfileClone/commit/7be1abd7d78c8ea769a18392464765f0982f56c4
Ahh got it!! Oh how I hate wasting time on such small things. so my scrolling was like this, which was making my control unclickable (for some weird reason)
if offset < 0 {
print(offset)
var headerTransform = CATransform3DIdentity
headerTransform = CATransform3DTranslate(headerTransform, 0, -offset, 0)
segmentedControl.layer.transform = headerTransform
} else {
var headerTransform = CATransform3DIdentity
headerTransform = CATransform3DTranslate(headerTransform, 0, max(-differenceToView, -offset), 0)
segmentedControl.layer.transform = headerTransform
}
when all I needed was
var segmentedControlTransform = CATransform3DIdentity
segmentedControlTransform = CATransform3DTranslate(segmentedControlTransform, 0, max(-differenceToView, -offset), 0)
segmentedControl.layer.transform = segmentedControlTransform
PS You can change your code to this
override func viewDidLoad() {
super.viewDidLoad()
UIApplication.sharedApplication().statusBarStyle = .LightContent
headerView.layer.zPosition = 1
containerView.layer.zPosition = 2
barView.layer.zPosition = 3
}
func subScrollViewDidScroll(scrollView: UIScrollView) {
let offset = scrollView.contentOffset.y
if offset < 0 {
var headerTransform = CATransform3DIdentity
let headerScaleFactor:CGFloat = -(offset) / headerView.bounds.height
let headerSizevariation = ((headerView.bounds.height * (1.0 + headerScaleFactor)) - headerView.bounds.height)/2.0
headerTransform = CATransform3DTranslate(headerTransform, 0, headerSizevariation, 0)
headerTransform = CATransform3DScale(headerTransform, 1.0 + headerScaleFactor, 1.0 + headerScaleFactor, 0)
headerView.layer.transform = headerTransform
} else {
var headerTransform = CATransform3DIdentity
headerTransform = CATransform3DTranslate(headerTransform, 0, max(-(headerView.bounds.height-min_header), -offset), 0)
headerView.layer.transform = headerTransform
}
if (headerView.bounds.height-min_header) < offset {
headerView.layer.zPosition = 3
} else {
headerView.layer.zPosition = 0
}
var barTransform = CATransform3DIdentity
barTransform = CATransform3DTranslate(barTransform, 0, max(-(headerView.bounds.height-min_header+bar_offset), -offset), 0)
barView.layer.transform = barTransform
}
Nice, glad you figured it out. The extra barView zPosition logic was just to avoid the slight visual issue of the bar overlapping the scrollbar.
A side question. Did you ever try to segue to ViewController and in the prepareForSegue tap into the ProfileViewController (specifically set a property there) ?
I haven't... maybe it could work by saving the ProfileViewController as a property on the ViewController within the ViewController's prepareForSegue? I'm not sure of the order of an embedded prepareForSegue.
Not sure I follow. I'm trying to set a user property in ProfileViewController from outside. So as I performSegue to ViewController I want o set the user so that ProfileViewController can deal with it. The problem is I can't tap into ViewController's container view's child?
Just tried it, and yeah you can't get at the container view child until the ViewController is fully initialized. A workaround might be to first set a property on the ViewController from the OtherViewController's prepareForSegue, then copy it over to the ProfileViewController in the ViewController's prepareForSegue (ugly but effective).
Yea pretty ugly. how did you get container view child when it was fully initialized? through ViewController's prepareForSegue ?
I wonder how twitter and the rest do it. I mean they must have a similar setup and need to set/pass a user their ProfileViewController.
I'm starting to think the ugly way is the right way. If you're doing custom header images, or showing other sub-views, the containing ViewController will need a reference to the user anyway. So the ViewController.user can be set in the OtherViewController.prepareForSegue, and ProfileViewController.user in ViewController.prepareForSegue.
Yea for now, I guess that will do. This container approach is the only way to do all this i guess. I mean we could have put it in UITableViewHeader and implement the functions to make it sticky, but then everything would be sticky. (Just thinking out loud)
There is a glitch with floating segmentedControl when you
self.tableView.insertRowsAtIndexPaths(newIndexPaths, withRowAnimation: .None)
That seems to call scrollViewDidScroll which calls out delegate.
Interesting... can you add as another issue with a little more info?
Hey,
I'm using a similar implementation for my profile UI. But in my ViewController I have a segmentedControl that floats. This all works except my touches aren't registered.
Did you try adding more than a UIImageView to the ViewController. For example a segmentedControl like Twitter UI has it?