iOS:iCarousel 中未选择视图的约束

Posted

技术标签:

【中文标题】iOS:iCarousel 中未选择视图的约束【英文标题】:iOS: Constraints on unselected view in iCarousel 【发布时间】:2013-12-20 14:30:47 【问题描述】:

我正在使用iCarousel 来显示我在 IB 中创建的自定义视图的实例。当轮播加载时,轮播中的第一个视图正确显示,如下所示:

但是,其他索引似乎忽略了我的约束,如下所示:

单击此视图后,布局会自行更正。另请注意,第一个索引现在有一个搞砸的布局:

知道如何纠正这个问题吗?我与轮播相关的代码:

- (NSUInteger)numberOfItemsInCarousel:(iCarousel *)carousel

    //return the total number of items in the carousel
    NSLog(@"size=%d",audio.count);
    return audio.count;


- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view

    NSLog(@"get view for index %d",index);
    Audio *aud = [audio objectAtIndex:index];

    CGRect screenRect = [[UIScreen mainScreen] bounds];
    CGFloat screenWidth = screenRect.size.width;
    CGFloat screenHeight = screenRect.size.height;

    AudioView *aView;

    float height = screenWidth*.5;
    float width = height * (16.0/9.0);

    //create new view if no view is available for recycling
    if (view == nil)
    


        aView = [[[NSBundle mainBundle] loadNibNamed:@"AudioView" owner:self options:nil] objectAtIndex:0];
        [aView setFrame:CGRectMake(0, 0, width, height)];


    else
        aView=(AudioView *)view;
    
    aView.layer.cornerRadius=8;
    NSLog(@"%f",aView.frame.size.height);
    NSLog(@"%f",aView.frame.size.width);


    aView.backgroundColor=[UIColor alizarinColor];
    aView.textLabel.text=aud.text;
    aView.titleLabel.text=aud.name;

    if (rowCurrentlyPlaying==index&&isPlaying) 
        aView.imageView.image = [UIImage imageNamed:@"pause.png"];
    else
        aView.imageView.image = [UIImage imageNamed:@"play.png"];
    



    return aView;


- (CGFloat)carousel:(iCarousel *)carousel valueForOption:(iCarouselOption)option withDefault:(CGFloat)value

    if (option == iCarouselOptionSpacing)
    
        return value * 1.1f;
    
    return value;


- (void)carousel:(iCarousel *)carousel didSelectItemAtIndex:(NSInteger)index
    NSLog(@"Clicked");
    if(index==self.carousel.currentItemIndex)
        Audio *aud = [audio objectAtIndex:index];
        NSURL *audUrl = [NSURL URLWithString:aud.audioUrl];

        if (rowCurrentlyPlaying==index) 
            if (isPlaying) 
                [anAudiostreamer pause];
                isPlaying=NO;
            else
                [anAudioStreamer play];
                isPlaying=YES;
            
        else
            rowCurrentlyPlaying=index;
            isPlaying=YES;


            aPlayerItem = [[AVPlayerItem alloc] initWithURL:audUrl];
            anAudioStreamer = [[AVPlayer alloc] initWithPlayerItem:aPlayerItem];
            [anAudioStreamer play];
        


        [carousel reloadData];

    


编辑:我也在 iPad 上尝试过,我认为这些屏幕截图可能有助于揭示一些信息(请忽略搞笑的字体大小)。看起来它在未选中时只是没有拉伸到全宽。

正确的布局:

不正确的布局:

【问题讨论】:

嗨詹姆斯,你有没有找到答案?我遇到了同样的问题。 【参考方案1】:

我整天都在寻找这个问题的答案——同样的事情也发生在我身上。设置自定义 UIView 的框架不起作用。

解决方法有点奇怪:

    转到自定义 UIView 的 xib 文件。我也会假设你 具有自定义 UIVIew 的相应子类(.h 和 .m 文件) 添加一个覆盖整个视图的子视图。我称之为背景视图。 将文本视图等添加为背景视图的子视图,并设置相对于背景视图的约束。 对于背景视图,添加以下约束:Top Space 到 Superview,Leading Space 到 Superview,宽度等于: , 高度等于: 创建两个出口,一个来自宽度约束,一个来自第 4 步的高度约束。这些出口应位于 自定义 UIView 的 .h 文件。

    在上面的viewForItemAtIndex 方法中,继续使用loadNibNamed 分配和初始化自定义视图 方法。但是,在那之后,设置宽度和高度约束 基于轮播边界的常量(或任何宽度和 你想要的高度)。例如,

    CustomView *customView = (CustomView *) view;
    customView.widthConstraint.constant = carousel.bounds.size.width;
    customView.heightConstraint.constant = carousel.bounds.size.height;
    

【讨论】:

没有工作,特别是因为你没有:宽度等于:,高度等于 是的,我愿意 - 查看第 4 条的结尾。 这个方法很好用。还要确保您将框架与约束一起设置。【参考方案2】:

我有一段时间没看 iCarousel,但这是来自我这里有的任何版本的自述文件

iCarousel supports the following built-in display types:

- iCarouselTypeLinear
- iCarouselTypeRotary
- iCarouselTypeInvertedRotary
- iCarouselTypeCylinder
- iCarouselTypeInvertedCylinder
- iCarouselTypeWheel
- iCarouselTypeInvertedWheel
- iCarouselTypeCoverFlow
- iCarouselTypeCoverFlow2
- iCarouselTypeTimeMachine
- iCarouselTypeInvertedTimeMachine

You can also implement your own bespoke carousel styles using `iCarouselTypeCustom` and the `carousel:itemTransformForOffset:baseTransform:` delegate method.

NOTE: The difference between `iCarouselTypeCoverFlow` and `iCarouselTypeCoverFlow2` types is quite subtle, however the logic for `iCarouselTypeCoverFlow2` is substantially more complex. If you flick the carousel they are basically identical, but if you drag the carousel slowly with your finger the difference should be apparent. `iCarouselTypeCoverFlow2` is designed to simulate the standard Apple CoverFlow effect as closely as possible and may change subtly in future in the interests of that goal.

我不确定您是否了解 iCourousel 正在对那些不是当前选择的视图应用变换,这是故意的。它在模拟 Apple 的封面流 api,(我们无法使用)..

好的,所以你的轮播对象有一个类型为 iCarouselType 的属性,称为 type,从上面的枚举中,最好的办法是尝试每一个来找到适合你的那个。

【讨论】:

谢谢。 “线性”轮播类型工作正常,所以我的问题一定是由于在未选择的视图上执行的转换。【参考方案3】:

我发现了一个看起来与 iCarousel 的通常实现不同的东西。

在方法- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view

我猜你需要使用:objectAtIndex:index]; 而不是objectAtIndex:0];

if (view == nil)

    aView = [[[NSBundle mainBundle] loadNibNamed:@"AudioView" owner:self options:nil] objectAtIndex:0];
    [aView setFrame:CGRectMake(0, 0, width, height)];

我在实时应用中使用了一段简单的代码:

- (UIView *)carousel:(iCarousel *)_carousel viewForItemAtIndex:(NSUInteger)index reusingView:(UIView *)view

if (view == nil)

    view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 200, 200)];
    view.contentMode = UIViewContentModeCenter;
    [view addSubview:[items objectAtIndex:index]];

else

    view = [items objectAtIndex:index];


view = [items objectAtIndex:index];

return view;

希望对您有所帮助。

【讨论】:

我不明白你的回答。我正在使用 objectAtIndex:0 因为 loadNibNamed 返回一个 NSArray 并且我想要它包含的第一个也是唯一一个视图。【参考方案4】:

当您在“viewForItemAtIndex”中创建音频视图时,您只需设置视图框架

[aView setFrame:CGRectMake(0, 0, width, height)];

我认为你必须设置aView的titlelabel和textlabel的框架,才能获得全宽文本。

对于第二个问题,当您单击视图时,该视图会正常显示,但前一个视图的文本会被剪切。

我认为您在点击时重新加载了所有轮播视图,

[轮播重载数据];

您只需要重新加载您被点击的那个视图。为此,您可以使用

(void)reloadItemAtIndex:(NSInteger)index 动画:(BOOL)animated;

愿这条线解决您的问题。

享受....

【讨论】:

【参考方案5】:

对我有帮助:

将带有 iCarousel 配置(数据源等)的函数移动到 viewDidAppearfunction。否则,我的框架不正确。

那么就这样写吧:

currentView?.frame.size.width  = carouselView.bounds.size.width
currentView?.frame.size.height = carouselView.bounds.size.height

希望对某人有所帮助

【讨论】:

以上是关于iOS:iCarousel 中未选择视图的约束的主要内容,如果未能解决你的问题,请参考以下文章

iCarousel - 动态更改中心项目 iOS

uiView 在 iOS10 的 ViewController 中未对齐,但不是 iOS11

如何在 iOS 中将选定的背景视图添加到 iCarousel?

如何在点击/选择时替换 iCarousel 中的特定视图?

使用 iCarousel ios 重用视图

iCarousels 卡在 iOS 7 中