nicklockwood / iCarousel

A simple, highly customisable, data-driven 3D carousel for iOS and Mac OS
http://www.charcoaldesign.co.uk/source/cocoa#icarousel
Other
12k stars 2.58k forks source link

Issue with CoverFlow type and using XIB as view #646

Open ghost opened 9 years ago

ghost commented 9 years ago

I have a strange issue that is causing all but my 1st view to have cutoff widths when using cover flow type and a xib file for the views. But if I change to 'Linear' type, the views all look fine and are full width. Ideas?

My setup is simple: Carousel is full screen and has auto layout setup to fit screen Xib file has two views: top view and bottom view equal sized with auto layout in place When running the app and loading the xib file in 'viewForItemAtIndex', the first view is shown beautifully. But once I start scrolling all the other views are cut in the width at varying sizes.

Here is my code:

// MARK: iCarouselDelegate
func carousel(carousel: iCarousel!, viewForItemAtIndex index: Int, reusingView view: UIView!) -> UIView!
{
    var carouselView = view as? SuCarouselSlideView
    if carouselView == nil
    {
        // Create new slide
        if let xibView = UINib(nibName: "SuCarouselSlideView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? SuCarouselSlideView
        {
            xibView.customInitWithFrame(carousel.bounds)
            carouselView = xibView
        }
    }

    // Update layout
    self.view.updateConstraintsIfNeeded()
    self.view.layoutIfNeeded()

    return carouselView
}

func customInitWithFrame(frame: CGRect)
{
    self.frame = frame
}
ghost commented 8 years ago

@NitWitStudios Did you find a solution to this issue? I'm having it as well.

I can add to this issue: iCarousel does not seem to respect Auto Layout. When I create views with frame-based layouts, it works. It does not work when that view uses auto layout. I am not aware of any simple fixes that can solve this.

ghost commented 8 years ago

Well the first item works with autolayout, but all the others don't.

ghost commented 8 years ago

@vrwim-bazookas I can't recall what I ended up doing exactly, but I think I just used the 'didRotateInterfaceOrientation' method to reload the data in iCarousel and rebuild the views. Hope that helps!

ghost commented 8 years ago

@NitWitStudios And you did this on the viewcontroller that you used the view from? Or the viewcontroller that contains the carousel? Because I am not finding it...

ghost commented 8 years ago

@vrwim-bazookas Honestly, I can't recall and unfortunately I no longer have access to the code for that app. However, I use iCarousel in a new app and I think I ended up using a static frame size for the views. Auto layout was just too complicated (maybe not feasible?). I only use portrait in my new app now, so don't have to worry about landscape, but if you need to have both I would say listen to the interface orientation change and reload the carousel data, then just add a method in there that detect what the interface orientation is and set to a specific frame size.

let CarouselViewSpacing: CGFloat = 2.0

func carousel(carousel: iCarousel, viewForItemAtIndex index: Int, reusingView view: UIView?) -> UIView {
    var cardView: CardView!

    if let dequeuedView = view as? CardView {
        cardView = dequeuedView
    } else if let xibView = UINib(nibName: "CardView", bundle: nil).instantiateWithOwner(nil, options: nil)[0] as? CardView
    {
        cardView = xibView
    }

    cardView.frame = CGRectMake(0, 20.0, carousel.bounds.width-50.0, carousel.bounds.height-20.0)        
    return cardView
}

func carousel(carousel: iCarousel, valueForOption option: iCarouselOption, withDefault value: CGFloat) -> CGFloat {
    if option == iCarouselOption.Spacing {
        return CarouselViewSpacing
    }
    return value
}