NSMutableArray难度 [英] NSMutableArray Difficulty

查看:106
本文介绍了NSMutableArray难度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果您想查看我遇到问题的代码,请点击以下链接:
代码



我的问题与我的过去的问题



我真的遇到了我的 NSMutableArray 的问题,我现在使用 iCarousel 为我的 slotMachine 对象(slot1和slot2)。我的应用程序以这种方式工作:



PhotoViewController 我创建了一个包含缩略图的视图,然后分配其框架按钮。因此,如果按下1个图像,它将通过 NSUserDefaults 保存该整数。
然后我将在我的 carouselViewController中检索它



我正在考虑调整数组,但我可以'吨。
我也在这里试过我的问题:
与NSMutableArray比较
如果我能像阵列2 那样做,那将会很容易,但仍然不能正常工作。



附加信息:)



我这样做了,有一个ViewController包含UIImageView,里面有一个按钮,所以当用户点击它,弹出我的 CustomPicker 。我的 CustomPicker 包含用户在相机胶卷上拾取的图像。因此,每个按钮都有一个特定值,使用 NSUserDefaults 发送到我的 iCarouselView 。第一个插槽的carousel1和第二个插槽的carousel2。



这就是我想做的事情:我想强行让它停在用户选择的索引上。 (我正在我的 carouselDidEndScrollingAnimtaion



在我的 carouselDidEndScrollingAnimation 方法我测试了我的所有条件(单独)它在比较方面完美地工作。
然后当我结合条件时,前两个比较或STOP是正确的,但接下来的两个总是错误的。或者有时混淆了。



我需要滚动两个特定的索引/整数,这是用户选择的(我已经完成了)能够滚动2对但是然后接下来的两个总是错的,因为我认为指数正在调整。



图片:



图片以下是我的 PhotoViewController ,其中包含我游戏的比较舞台 SETTING UIImageVIew UIButton 。将根据它放入数字的图像将是强制性的,应该强制显示。





当我的iCarousel启动时它会停止,例如在下面的图片中(与上面的图片不同):



将强行滚动到 PhotoViewC中输入的图像ontroller



进入:



摘要:
就像这样。我从那里有一个 settingsView ,我将导入我的图像(多个) Slot1 & 时隙2
然后在另一个视图中显示上面图像的 PhotoViewController 。第一列对应第一个插槽,后面是第二个插槽。如果按下一个视图(例如 No。1 Slot 1 ,它将加载加载图像的图像缩略图从 Picker 中选择 Slot 1



你必须这样做4次(对)---->显示在这里我通过NSUserDefaults通过button.tag得到他们的索引然后发送到 iCarouselView



然后当你完成后(按完成按钮)它将转到 iCarouselView 然后,如上图所示那是它的视图。
按下它时会旋转几秒钟,然后完成但不会停在 PhotoView中选择的用户它会强行滚动到该指数。



问题:



有没有办法让我的数组或我的iCarousel.view在我删除时不调整它们的索引。仍然保留我的索引正确的方法。或者是否有其他解决方案,如调整我的数组,就像调整我的 PhotoView中控制器也选择了索引。因为我认为当我的数组保留索引甚至删除时我就能解决这个问题。但仍然不能。



希望你理解我的问题。

解决方案

< blockquote>

有没有办法让我的数组或我的iCarousel.view在我删除时不调整它们的索引。仍然以正确的方式保留我的索引。或者是否有其他解决方案,如调整我的数组,就像调整我的PhotoViewController选择索引一样。因为我认为当我的数组保留索引甚至删除时我就能解决这个问题。但仍然不能。


修改iCarousel管理索引的方式的唯一方法是修改代码。实际上,如果你查看iCarousel.m中的 removeViewAtIndex 方法,你会看到索引是通过NSDictionary管理的,并且在删除时,字典被重新排列(物品重新订购)。您可以使用该方法:

   - (void)removeViewAtIndex:(NSInteger)index 
{
NSMutableDictionary * newItemViews = [NSMutableDictionary dictionaryWithCapacity:[itemViews count] - 1];
for(NSNumber * [self indicesForVisibleItems]中的数字)
{
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 / slot4?),您还应该在删除元素后更新它们的值。



另一方面,我认为你在这里问的是如何做一些你认为能解决问题的事情,但你并没有真正解释问题所在。事实上,如果我理解正确,你所做的是:


  1. 旋转旋转木马;


  2. 当轮播停止时,如果在所需项目上没有偶然的机会,则强制它滚动到该项目。


删除一些元素之后没有理由不这样做(除非iCarousel有一些错误,然后解决方案就是捕获bug)。唯一的部分是知道哪个索引是你想要转移的索引。



作为一个建议,我首先要简化你的委托 carouselDidEndScrollingAnimation 方法。实际上,你的 carouselDidEndScrollingAnimation 有一个名为 carousel 的参数,好吧,我认为这是你应该引用的唯一轮播以那种方法。如果您没有看到,这就是原因:您的每个轮播将停止滚动,并且将调用 carouselDidEndScrollingAnimation ;这样方法将被调用两次。每次执行该方法时,您将修改carousel1和carousel2的状态(通过调用 scrollToItemAtIndex );因此,在每个旋转木马上,你会拨打 scrollToItemAtIndex 两次。



这对我来说听起来不太正确。所以你应该找到一种方法,当为carousel1调用 carouselDidEndScrollingAnimation 时只滚动carousel1,并且当 carouselDidEndScrollingAnimation

更一般地说,我想提出的另一点是:


  1. 让旋转木马停止;


  2. 再次滚动它以使其到达所需位置;


似乎不是最好的实现,因为用户会看到轮播停止然后重新开始。



我接近这个的方法是直接修改iCarousel实现,以便它支持你需要的这种特定行为。



具体来说,看看iCarousel.m中的步骤方法。在每个帧处调用此方法以生成轮播动画。现在,在这种方法中有减速分支:

 否则如果(减速)
{
CGFloat time = fminf(scrollDuration,currentTime - startTime);
CGFloat acceleration = -startVelocity / scrollDuration;
CGFloat距离= startVelocity *时间+ 0.5f *加速度* powf(时间,2.0f);
scrollOffset = startOffset + distance;

[self didScroll];
if(time ==(CGFloat)scrollDuration)
{
减速= 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)
{
//调用滚动触发事件以获取遗留支持的原因
//即使从技术上讲我们也不需要滚动所有
[self scrollToItemAtIndex :self.currentItemIndex duration:0.01];
}
else
{
[self scrollToItemAtIndex:self.currentItemIndex animated:YES];
}
}
其他
{
CGFloat差异=(CGFloat)self.currentItemIndex - scrollOffset / itemWidth;
if(差异> 0.5)
{
差异=差异 - 1.0f;
}
else if(差异< -0.5)
{
差异= 1.0 +差异;
}
toggleTime = currentTime - MAX_TOGGLE_DURATION * fabsf(差异);
toggle = fmaxf(-1.0f,fminf(1.0f,-difference));
}
}
}

你看到的是旋转木马停止减速,再次滚动。这与您正在进行的完全相同,因此您可能会找到一种方法来修改此代码,并使轮播完全滚动到您需要的索引。通过这种方式,您可以更加平滑地旋转旋转木马。



希望这有助于为长篇回复道歉。


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.

解决方案

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.

The only way you have to modify the way iCarousel manages its indexes is by modifying the code. Indeed, if you look at the removeViewAtIndex method in iCarousel.m, you will see that indexes are managed through an NSDictionary, and at the moment of deleting, the dictionary is rearranged (items are reordered). You could take that method:

- (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;
}

You could apply the same logic to your array, so that the carousel and your array keep in sync. Of course, if you store the indexes somewhere (slot1/slot2/slot2/slot4?), you should also update their values after removing an element.

On the other hand, I think that what you are asking here is how to do something that you believe would solve the problem you have, but you are not really explaining what the problem is. Indeed, if I understand you correctly, what you do is:

  1. spinning the carousel;

  2. when the carousel stops, if it is not by chance on the desired item, you "force" it to scroll to that item.

There is no reason why this should not work after deleting some elements (unless iCarousel has some bugs, then the solution would be catching the bug). The only part is knowing which index is the one you would like to move to.

As a suggestion, I would start off by simplifying your delegate carouselDidEndScrollingAnimation method. Indeed, your carouselDidEndScrollingAnimation has a parameter called carousel, well, I think this is the only carousel you should ever be referring to in that method. If you don't see it, this is the reasoning: each of your carousel will stop scrolling and the carouselDidEndScrollingAnimation will be called; so that method will be called twice. Each time that method is executed you will modify the state of both carousel1 and carousel2 (by calling scrollToItemAtIndex); therefore, on each carousel you will call scrollToItemAtIndex twice.

This does no sound very correct to me. So you should find a way to scroll only carousel1 when carouselDidEndScrollingAnimation is called for carousel1 and to scroll only carousel2 when carouselDidEndScrollingAnimation is called for carousel2.

More generally, another point I would like to raise is that the idea of:

  1. letting a carousel stop;

  2. scrolling it again so that it reaches the desired position;

does not seem the best implementation possible since the user would see the carousel stopping and then starting over again.

The way I would approach this is by modifying directly iCarousel implementation so that it supports this specific behavior you need.

Concretely, give a look at the step method in iCarousel.m. This is called at each frame to produce the carousel animation. Now, in this method there is decelerating branch:

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));
        }
    }
}

and you see that when the carousel stops decelerating, it is scrolled again. This is exactly the same as you are doing, so you might find a way to modify this code and have the carousel scrolls exactly to the index you need. In this way you would get a far smoother spinning of the carousel.

Hope this helps and apologies for the lengthy reply.

这篇关于NSMutableArray难度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆