1

我正在尝试开发一个库,它采用一组图像并返回一个滚动视图,其中每个图像并排。

但是,当我添加此滚动视图时,我将返回到我的主视图,它不会添加图像。图像是正确的。

我的想法是使用滚动视图与每个图像并排,并使用滚动条像幻灯片放映一样显示。首先,这个概念好吗?

其次,我不明白为什么在模拟器中运行应用程序时没有显示图像。

需要更多详细信息,请询问。

代码如下。我的头文件:

#import <UIKit/UIKit.h>

@interface HCIImageSlideShowView : UIScrollView

-(void) setImages:(NSArray*) imagesArray;
-(void) setBounds:(CGRect)bounds;
-(void) setCaptions:(NSArray*) imageCaptionsArray;

-(void) isEditable:(BOOL)edit;

-(void) setSlideTime:(int) milliSeconds;

-(void) startSlideShow;

- (id) initWithImages:(NSArray*)imagesArray captionsArray:(NSArray*) captionArray
               bounds:(CGRect)bounds slideTime:(int)milliSeconds;

@end

我的实现文件:

#import "HCIImageSlideShowView.h"
#import "HCIResultListViewController.h"

@interface HCIImageSlideShowView ()

@property (strong,nonatomic) NSMutableArray *imagesArray;
@property BOOL editable;
@property (nonatomic)  int slideTime;
@property (strong,nonatomic) NSMutableArray *imageCaptionsArray;
@property CGFloat width;

@end


@implementation HCIImageSlideShowView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
    }
    return self;
}

- (id) initWithImages:(NSArray*)imagesArray captionsArray:(NSArray*) captionArray
               bounds:(CGRect)bounds slideTime:(int)milliSeconds
{

    NSLog([NSString stringWithFormat:@"%f,%f", bounds.size.width , bounds.size.height]);

    CGFloat width_t = bounds.size.width;

    bounds.size.width = [imagesArray count] * bounds.size.width;

    self = [[HCIImageSlideShowView alloc] initWithFrame:bounds];

    _width = width_t;

    [self setBackgroundColor:[[UIColor alloc] initWithRed:0.2 green:0.1 blue:0.3 alpha:0.4]];

     if (self) {
        [self setImages:imagesArray];
        [self setSlideTime:milliSeconds];
        [self setCaptions:captionArray];
        [self defaultLoad];
    }

    self.scrollEnabled = YES;

    return self;
}

-(void) defaultLoad
{

    NSLog([NSString stringWithFormat:@"%f,%f,%f",_width,self.bounds.size.height,self.bounds.size.width]);

    for (int i = 0; i < [_imagesArray count]; i++) {
        CGRect imageBounds = CGRectMake(i * _width, self.bounds.size.height, _width, self.bounds.size.height);
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:imageBounds];
        [imageView setImage:[HCIResultListViewController resizeImage:_imagesArray[i] withWidth:_width withHeight:self.bounds.size.height]];
        NSLog([NSString stringWithFormat:@"%f,%f",imageView.bounds.size.height,imageView.bounds.size.width]);
        [self addSubview:imageView];
    }

}

-(void) setBounds:(CGRect)bounds
{
    self.bounds = bounds;
}

-(void) setImages:(NSArray *)imagesArray
{
    _imagesArray = [[NSMutableArray alloc] initWithArray:imagesArray];
}

-(void) setSlideTime:(int)milliSeconds
{
    _slideTime = milliSeconds;
}

-(void) startSlideShow
{

}

-(void) isEditable:(BOOL)edit
{
    _editable = edit;
}

-(void) setCaptions:(NSArray *)imageCaptionsArray {
    _imageCaptionsArray = [[NSMutableArray alloc] initWithArray:imageCaptionsArray];
}

@end
4

2 回答 2

2

您的代码似乎有很多问题 - 特别是您的初始化程序。这是一个评论版本

@interface HCIImageSlideShowView : UIScrollView


-(void) startSlideShow;

- (id) initWithImages:(NSArray*)imagesArray captionsArray:(NSArray*) captionArray
               bounds:(CGRect)bounds slideTime:(int)milliSeconds;
    /*
     remove this custom initialiser as it is quite wrong. 
     Use the default initialiser (don't override) 
     then set the properties after you have created the object. 
     */


    /* Remove all of your custom setters. 
    If any of these properties need setting outside of the class, 
    move the property declarations to the .h file.
    */ 

     -(void) setImages:(NSArray*) imagesArray;
     -(void) setBounds:(CGRect)bounds;
     -(void) setCaptions:(NSArray*) imageCaptionsArray;

     -(void) isEditable:(BOOL)edit;

     -(void) setSlideTime:(int) milliSeconds;

@end



    #import "HCIImageSlideShowView.h"
    #import "HCIResultListViewController.h"

@interface HCIImageSlideShowView()
/*
make these properties public by moving them to your .h file 
so that you can set them from the calling object
*/
@property (strong,nonatomic) NSMutableArray *imagesArray;
@property BOOL editable;
@property (nonatomic)  int slideTime;
@property (strong,nonatomic) NSMutableArray *imageCaptionsArray;
@property CGFloat width;
@end

@implementation HCIImageSlideShowView

 - (id) initWithImages:(NSArray*)imagesArray captionsArray:(NSArray*) captionArray
               bounds:(CGRect)bounds slideTime:(int)milliSeconds
/*
     You seem to be getting confused with init, 
     so I suggest you do not make a custom init method at all. 
     Initialise your object with the default initWithFrame, 
     then have the caller set properties on your newly 
         made object after initiliasation.

*/

{
     NSLog([NSString stringWithFormat:@"%f,%f", bounds.size.width , bounds.size.height]);
    /*
      This is the way to use NSLog...
      NSLog(@"%f,%f", bounds.size.width , bounds.size.height);
     */

    CGFloat width_t = bounds.size.width;
    /*
     double assignment: two lines further down you assign 
    width_t to _width. You can do that here in one step
     */

    bounds.size.width = [imagesArray count] * bounds.size.width;

    self = [[HCIImageSlideShowView alloc] initWithFrame:bounds];

    /*
     This is wrong. Although as Hermann says it may be _legal_, don't do it!
         -Never alloc an object inside it's own initialiser. 
         The memory will already have been alloc'd by the caller. 
         - Never assign to self anything but the return value from super's init.
     */

    _width = width_t;

    /*
     please be consistent with your iVar/property naming. 
     Here you are addressing the ivar _width, 2 lines up 
     you are using the property accessor syntax self.bounds. 
     In you case I would recommend ALWAYS using self.varName 
     except inside a custom setter or getter. 
     */

    [self setBackgroundColor:[[UIColor alloc] initWithRed:0.2 green:0.1 blue:0.3 alpha:0.4]];

    if (self) {
            //[self setImages:imagesArray];
        self.imagesArray = [imagesArray mutableCopy];

            //[self setSlideTime:milliSeconds];
        self.slideTime = milliSeconds;

            //[self setCaptions:captionArray];
        self.imageCaptionsArray = [captionArray mutableCopy];

        /*
         As my comment above - use property syntax and try to 
         avoid writing your own setters and getters 
         unless you have a very good reason.
         */

        [self defaultLoad];
    }

    self.scrollEnabled = YES;

    return self;
}

由于您的初始化代码需要重新排列,因此我没有仔细查看defaultLoad-但是我确实有一些观察...

(1)

CGRect imageBounds = CGRectMake(i * _width, self.bounds.size.height, _width, self.bounds.size.height);

应该

    CGRect imageBounds = CGRectMake(i * _width,0, _width, self.bounds.size.height);

否则,您的图像都将放置在您的滚动视图高度下方的屏幕外。

(2)

您需要设置 contentSize 以便 scrollView 可以滚动

[scrollView setContentSize:(CGSize){self.width*[imageArray count],self.bounds.size.height}];

另一个更一般的评论是,这对于一些图像来说是可以的,但是你不希望使用大量的屏幕外图像视图来制作滚动视图,因为你会占用内存。您实际上只需要三个,用于当前屏幕上的图像,以及左右的上一个和下一个图像。这个想法是仅在您可能需要它们时才加载您的图像,并以 tableView 的工作方式回收您的 imageViews。

您应该查看Apple 的 Photoscroller 示例应用程序以及随附的 WWDC 2010/11 视频和幻灯片

不要担心平铺和缩放的所有细节,最好掌握将对象创建保持在最低限度并在可行的情况下回收/重用对象的一般原则。

顺便说一句,您可能根本不需要自定义的 scrollView 对象:您可以通过调用 viewController 对象的几行代码来实现您所追求的大部分内容。例如...

- (void) viewDidLoad {
        [super viewDidLoad];
    UIScrollView* scrollView = [[UIScrollView alloc] initWithFrame:self.view.bounds];
    [scrollView setBackgroundColor:[UIColor redColor]];
    NSArray* imageArray = @[[UIImage imageNamed:@"image1.png"]
                            ,[UIImage imageNamed:@"image2.png"]
                            ,[UIImage imageNamed:@"image3.png"]
                            ];
    CGFloat width = scrollView.bounds.size.width;
    CGFloat height = scrollView.bounds.size.height;

    for (int i = 0; i < [imageArray count]; i++) {
        CGRect imageFrame = CGRectMake(i * width, 0, width, height);
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:imageFrame];
        [imageView setImage:imageArray[i]];
        [scrollView addSubview:imageView];
    }
    [scrollView setContentSize:(CGSize){width*[imageArray count],height}];
    [self.view addSubview:scrollView];
}
于 2013-03-18T16:08:33.263 回答
0
- (id) initWithImages:(NSArray*)imagesArray captionsArray:(NSArray*) captionArray
               bounds:(CGRect)bounds slideTime:(int)milliSeconds
{

    NSLog([NSString stringWithFormat:@"%f,%f", bounds.size.width , bounds.size.height]);

    CGFloat width_t = bounds.size.width;

    bounds.size.width = [imagesArray count] * bounds.size.width;

    self = [self initWithFrame:bounds];

    _width = width_t;

    [self setBackgroundColor:[[UIColor alloc] initWithRed:0.2 green:0.1 blue:0.3 alpha:0.4]];

     if (self) {
        [self setImages:imagesArray];
        [self setSlideTime:milliSeconds];
        [self setCaptions:captionArray];
        [self defaultLoad];
    }

    self.scrollEnabled = YES;

    return self;
}
于 2013-03-18T14:11:23.517 回答