-->

NSMutableArray的难度(NSMutableArray Difficulty)

2019-07-30 02:32发布

If you wanna see the code Im having problem with, here is the link: Code

My question is connected with my past question.

I'm really having problem with my NSMutableArray, I'm currently using iCarousel for my slotMachine object(slot1 and slot2). My app works this way:

From PhotoViewController I made a view that has thumbnail images, then assign its frame with button. So if 1 image was pressed, it will save that integer via NSUserDefaults. Then I will retrieve it in my carouselViewController

Im thinking of adjusting the array but I can't. I also have tried my question here: Comparing with NSMutableArray If only I can do it the same as Array 2 it would be much easy, but still not working.

(ADDITIONAL INFO:)

I have done it this way, have a Viewcontroller that contains the UIImageView with a button in it, so when the user taps it, my CustomPicker pops up. My CustomPicker contains the image on what the user have picked on the camera roll. So each button has a specific value sent to my iCarouselView using NSUserDefaults. carousel1 for First slot and carousel2 for Second slot.

Here is what I wanna do: I want to forcefully make it stop to the index the user picks. (Which Im doing in my carouselDidEndScrollingAnimtaion)

In my carouselDidEndScrollingAnimation method i tested all of my condition(individually) it works perfectly in terms of comparing. Then when I combine the conditions, the first Two comparison or STOP is RIGHT, but the next two are always wrong. Or sometimes Got mixed up.

I need to scroll the two specific indexes/integer which was User Picked( I already done that) was able to scroll 2 pairs of them but then the next two were always wrong because I think there indexes were adjusting.

PICTURES:

Image Below is my PhotoViewController which contained the Comparing Stage SETTING of my game.UIImageVIew with UIButton.Image that will be put in the number according to it will be Forcefully and should be forcefully shown.

When my iCarousel start then it stops for example in the image below(Which is not the same as the above):

Will be forcefully scroll to the inputted image in the PhotoViewController

Into:

Summary: Its like this. I have a settingsView from there, I will import my images(Multiple) for Slot1 & Slot2. Then in another View the PhotoViewController that is where the image above is shown. THe first column corresponds to 1st slot followed by the 2nd slot. if a view is pressed (for example No. 1 of Slot 1 it will load a thumbnail of images loading the images picked from Picker for the Slot 1.

You will have to do it 4 times(pair) ----> The displayed here I get their indexes via NSUserDefaults via button.tag then send to iCarouselView.

Then when you are done (pressed Done button) it will go to iCarouselView then, as shown above thats the view of it. When pressed it will spin for couple of seconds, then when finished but not stop at the user picked in the PhotoView it will forcefully scroll to that index.

QUESTION:

Is there a way to make my array or my iCarousel.view not adjust their indexes when Im deleting. To still retain my indexes the right way. Or are there other solution like adjusting my array, the same as adjusting my PhotoViewController picked indexes too. Because I think that when my array retain their indexes even deleting I would be able to solve this problem. But still can't.

Hope you understand my question.

Answer 1:

有没有办法让我的数组或我的iCarousel.view不调整自己的索引时林删除。 为了仍然保留我的索引以正确的方式。 还是有其他的解决办法像我调整阵列,同样作为调整我的PhotoViewController挑选指标了。 因为我想,当我的数组保留其指标甚至删除我能解决这个问题。 但仍不能。

你必须修改iCarousel管理其索引方式的唯一方法是通过修改代码。 事实上,如果你看一下removeViewAtIndex在iCarousel.m方法,你会看到,指标是通过一个NSDictionary管理,并在删除的那一刻,字典重排(项目进行重新排序)。 你可以采取这种方法:

- (void)removeViewAtIndex:(NSInteger)index
{
    NSMutableDictionary *newItemViews = [NSMutableDictionary dictionaryWithCapacity:[itemViews count] - 1];
    for (NSNumber *number in [self indexesForVisibleItems])
    {
        NSInteger i = [number integerValue];
        if (i < index)
        {
            [newItemViews setObject:[itemViews objectForKey:number] forKey:number];
        }
        else if (i > index)
        {
            [newItemViews setObject:[itemViews objectForKey:number] forKey:[NSNumber numberWithInteger:i - 1]];
        }
    }
    self.itemViews = newItemViews;
}

您可以应用相同的逻辑来你的阵列,使转盘和您的阵列保持同步。 当然,如果您存储索引某处(SLOT1 / SLOT2 / SLOT2 /时隙4?),你也应该移除元素之后更新它们的值。

在另一方面,我认为你问这里是如何做到这一点,你认为会解决你有问题的东西,但你并没有真正解释的问题是什么。 事实上,如果我理解正确的话,你做的是:

  1. 旋转转盘;

  2. 转盘停止时,如果不是通过所需的项目机会,你“逼”它滚动到该项目。

没有理由为什么这个不应该删除某些内容(除非iCarousel有一些错误,那么解决方案将被捕获的bug)后工作。 唯一的部分是要知道哪个索引你想移动到一个。

作为一个建议,我会通过简化您的委托开始carouselDidEndScrollingAnimation方法。 事实上,你的carouselDidEndScrollingAnimation有一个名为参数carousel ,好了,我觉得这是你曾经在该法指的是只转盘。 如果你没有看到它,这是一个道理:每个转盘将停止滚动和carouselDidEndScrollingAnimation将被调用; 使方法会被调用两次。 每次被执行的方法,你会修改这两个carousel1和carousel2的状态(通过调用scrollToItemAtIndex ); 因此,每个旋转木马,你会打电话给scrollToItemAtIndex两次。

这确实没有声音对我来说非常正确的。 所以,你应该找到一种方法,只滚动时carousel1 carouselDidEndScrollingAnimation被调用carousel1当滚动仅carousel2 carouselDidEndScrollingAnimation被调用carousel2。

更一般地,另一点我想提出的是,这个想法的:

  1. 让转盘停止;

  2. 再次滚动,以便它到达期望的位置;

似乎不是最好的实现可能的,因为用户将看到传送带停止,然后再重新开始。

我将接近这一问题的方法是使之支持,你需要这个特定的行为直接修改iCarousel实施。

具体而言,给一看step的iCarousel.m方法。 这就是所谓的在每一帧,以产生所述转盘动画。 现在,这种方法有decelerating分支:

else if (decelerating)
{
    CGFloat time = fminf(scrollDuration, currentTime - startTime);
    CGFloat acceleration = -startVelocity/scrollDuration;
    CGFloat distance = startVelocity * time + 0.5f * acceleration * powf(time, 2.0f);
    scrollOffset = startOffset + distance;

    [self didScroll];
    if (time == (CGFloat)scrollDuration)
    {
        decelerating = NO;
        if ([delegate respondsToSelector:@selector(carouselDidEndDecelerating:)])
        {
            [delegate carouselDidEndDecelerating:self];
        }
        if (scrollToItemBoundary || (scrollOffset - [self clampedOffset:scrollOffset]) != 0.0f)
        {
            if (fabsf(scrollOffset/itemWidth - self.currentItemIndex) < 0.01f)
            {
                //call scroll to trigger events for legacy support reasons
                //even though technically we don't need to scroll at all
                [self scrollToItemAtIndex:self.currentItemIndex duration:0.01];
            }
            else
            {
                [self scrollToItemAtIndex:self.currentItemIndex animated:YES];
            }
        }
        else
        {
            CGFloat difference = (CGFloat)self.currentItemIndex - scrollOffset/itemWidth;
            if (difference > 0.5)
            {
                difference = difference - 1.0f;
            }
            else if (difference < -0.5)
            {
                difference = 1.0 + difference;
            }
            toggleTime = currentTime - MAX_TOGGLE_DURATION * fabsf(difference);
            toggle = fmaxf(-1.0f, fminf(1.0f, -difference));
        }
    }
}

你看,当转盘停止减速,它再次滚动。 这是因为你正在做的完全一样的,所以你可能会找到一个方法来修改这个代码,并有转盘滚动正是你所需要的指标。 这样,你会得到转盘的更平滑的旋转。

希望这有助于和冗长的答复道歉。



Answer 2:

它有点难以知道的问题是在这里。 您是否使用单一的NSMutableArray的图像,并用值NSUserDefaults的获取数组中的索引处的对象?

我不是100%确定发生了什么。 什么是用户做的(以及以何种观点),什么是后触发(该视图呈现)。

你们是不是要停止是一样的一个从之前挑选的图像上的“旋转”的图片?

根据以上的图像时,图像是关闭的一个指标。 这是每一个时间的情况下? 也许有从阵列获取的一个问题。

如果你给我一些更多的信息,我可以帮忙。

我通过代码看你再粘贴,我觉得这可能是你的问题

if (twoSlot1 > [(UIImageView*)[self.carousel2 currentItemView] tag]){            
                [self.carousel1 scrollToItemAtIndex:(-twoSlot1)-2 duration: 3.5f];
            } else {
                [self.carousel1 scrollToItemAtIndex:-twoSlot1 duration: 3.5f];
            }

在所有其他代码块一样,你有这样的地方,你调用每个转盘。 在上面的代码中调用转盘1的两倍。

if (slot2 > [(UIImageView*)[self.carousel1 currentItemView] tag]){
            [self.carousel1 scrollToItemAtIndex:(-slot2)-2 duration: 3.0f];
            } else {
            [self.carousel1 scrollToItemAtIndex:-slot2 duration: 3.0f];    
            }

            if (twoSlot2 > [(UIImageView*)[self.carousel2 currentItemView] tag]){
            [self.carousel2 scrollToItemAtIndex:(-twoSlot2)-2 duration: 3.5f];    
            } else {
            [self.carousel2 scrollToItemAtIndex:-twoSlot2 duration: 3.5f];
            }

你叫self.carousel1时,你应该主叫号码2。

它是否正确?



Answer 3:

参考你的问题。 你要当一个成员从阵列中删除不改变其成员的索引的数组。

我想你可以使用一个NSMutableDictionary。 这是一个关联数组如此说来,这里的指标是你选择的,当你在删除之间的成员,他们保持不变。 您仍然可以使用0到n的索引。 您仍然可以使用一些方法,你所熟悉的NSArray的,如计数。 您可以使用一个枚举去翻翻字典中的所有成员。 在另一方面,你仍然可以使用你的for循环,你是用来与阵列中使用它们。 只要准备在于:a)objectForKey:i可以返回nil如果键/索引不存在(例如已被删除),并且将该数retuns的对象的数量,但不是最高的索引+ 1,因为它与阵列一样。



Answer 4:

不知道如果我完全理解,但是当你的可变数组的元素之一被删除,而不只是删除它,也许有另一种“伪”占位符对象中插入呢? 这样,当删除您的出现索引将不会改变



Answer 5:

我有一个很难理解你的整体问题,但是从我可以收集你的问题的症结是:

有没有办法让我的数组或我的iCarousel.view不调整自己的索引时林删除。

我不知道是否会解决您的比较大的问题,但使用一个NSMutableDictionary模拟阵列应该让你做到这一点。 你可以简单地使用指数作为键的字典,然后当你删除与索引相关的项目,没有其他的指标将调整结果。 例如:

NSMutableDictionary *arrayDict = [[NSMutableDictionary alloc] init];
[arrayDict setValue:foo forKey:[NSNumber numberWithInt:[arrayDict count]]];
[arrayDict setValue:bar forKey:[NSNumber numberWithInt:[arrayDict count]]];
[arrayDict setValue:fooBar forKey:[NSNumber numberWithInt:[arrayDict count]]];

然后你可以在索引访问对象的[arrayDict objectForKey:[NSNumber numberWithInt:index]]

需要注意的是使用一个NSNumber的setValue方法的关键参数:forKey:会生成一个警告,但可以放心地忽略这一点(或使用字符串表示,如果你烦恼)。



文章来源: NSMutableArray Difficulty