LazyScrollViewIntroduction to the

LazyScrollView inherits from ScrollView and aims to solve the reuse and recycling problem of heterogeneous (isomorphic contrast with TableView) scrolling view. It supports reuse across View layers, generating a high performance scrolling View in an easy-to-use manner. This scheme was first implemented on the home page of tmall iOS client.

—- Apple core – iOS high performance heterogeneous scroll view construction solution — LazyScrollView

In this article, the blogger introduced the use and implementation scheme of LazyScrollView in detail, but did not give a specific DEMO. Here, I just stand on the shoulders of giants and give a DEMO, but also hope to throw a brick to attract others.

LazyScrollViewuse

Id

dataSource; The following three interfaces need to be implemented:

@protocol LazyScrollViewDataSource <NSObject> @required // How many items are displayed in the ScrollView (NSUInteger)numberOfItemInScrollView:(LazyScrollView *)scrollView; RectModel - (LSVRectModel *)scrollView:(LazyScrollView *)scrollView rectModelAtIndex:(NSUInteger)index; // return the view - (UIView *)scrollView:(LazyScrollView *)scrollView itemByLsvId:(NSString *)lsvId; @endCopy the code

Where LSVRectModel is TMMuiRectModel in the original text:

@interface LSVRectModel: NSObject // Converted absolute value rect @property (nonatomic, assign) CGRect absRect; // business subscript @property (nonatomic, copy) NSString *lsvId; + (instancetype)modelWithRect:(CGRect)rect lsvId:(NSString *)lsvId; @endCopy the code

All three interfaces are very simple, very similar to UITableView, if you don’t know, you can check out the DEMO or the text at the bottom.

In addition, LazyScrollView provides three interfaces, which are modeled after UITableView, so the entire LazyScrollView should be easy to use:

- (void)reloadData;
- (UIView *)dequeueReusableItemWithIdentifier:(NSString *)identifier;
- (void)registerClass:(Class)viewClass forViewReuseIdentifier:(NSString *)identifier;
Copy the code

LazyScrollViewimplementation

The main idea is reuse, so there are two View pools:

@property (nonatomic, strong) NSMutableDictionary<NSString *, NSMutableSet *> *reuseViews;
@property (nonatomic, strong) NSMutableSet<__kindof UIView *> *visibleViews;
Copy the code

Since each View may correspond to a different identifier, reuseViews is an NSMutableDictionary. When a View slides out of the visible area, it is first removed from visibleViews, then added to reuseViews, and removed from LazyScrollView, calling removeFromSuperview. This place may be misunderstood by the author in the original text.

LazyScrollView has a Dictionary, the key is reuseIdentifier, and the Value is the View corresponding to the reuseIdentifier that is recycled, and when the LazyScrollView knows that the View should no longer appear, I’m going to put the View here, and I’m going to drop the View hidden.

Here the author is using hidden drop, but we know that hidden is just controlling the visible and hidden, and the View itself is still there and can’t be reused.

When a View slides into the visible area, it needs to reuse it from reuseViews first. If reuseViews does not exist, it needs to create a new one. Related implementation see – (UIView *) dequeueReusableItemWithIdentifier (nsstrings *) identifier; .

The last question is how to determine if a View is in the visible area. Here the original text is very clear, there are pictures to match. I suggest you move on to the original text. Y +CGRectGetHeight(self.bounds) + BUFFER_HEIGHT, And then the intersection of the two sets is the View set that needs to be displayed. Of course, there are some processing algorithms:

  • Ascending the top edge gives you a set, descending the bottom edge gives you a set.
  • Use dichotomy to find the appropriate location, and then take a subset of the set obtained in the previous step.

Ok, so much said, let’s release the DEMO address first, I hope you can help improve, also hope to give a Star. Github.com/HistoryZhan… . Apple core – iOS high performance heterogeneous scroll view construction solution — LazyScrollView (there is a lot of dry stuff in it).

Finally, let’s talk about the problems we have written so far, and hope we can optimize them together:

  1. No processingViewClick on the event, i.e. no writedelegateThe callback.
  2. The algorithm needs to be optimized when dichotomy searches for the appropriate position.
  3. From the oldvisibleViewsRemove the slider from theViewThe algorithm needs to be optimized.

Post the code for the second question:

- (NSMutableSet *)findSetWithMinEdge:(CGFloat)minEdge {
    NSArray *ascendingEdgeArray =
    [self.allRects sortedArrayUsingComparator:^NSComparisonResult(LSVRectModel *obj1, LSVRectModel *obj2) {
        return CGRectGetMinY(obj1.absRect) > CGRectGetMinY(obj2.absRect) ? NSOrderedDescending : NSOrderedAscending; }]; // dichotomy NSInteger minIndex = 0; NSInteger maxIndex = ascendingEdgeArray.count - 1; NSInteger midIndex = (minIndex + maxIndex) / 2; LSVRectModel *model = ascendingEdgeArray[midIndex];while (minIndex < maxIndex - 1) {
        if (CGRectGetMinY(model.absRect) > minEdge) {
            maxIndex = midIndex;
        }
        else {
            minIndex = midIndex;
        }
        midIndex = (minIndex + maxIndex) / 2;
        model = ascendingEdgeArray[midIndex];
    }
    midIndex = MAX(midIndex - 1, 0);
    NSArray *array = [ascendingEdgeArray subarrayWithRange:NSMakeRange(midIndex, ascendingEdgeArray.count - midIndex)];
    return [NSMutableSet setWithArray:array];
}
Copy the code

Here’s another code for question 3:

    NSMutableArray *newVisibleViews = [self visiableViewModels].mutableCopy;
    NSMutableArray *newVisibleLsvIds = [newVisibleViews valueForKey:@"lsvId"];
    NSMutableArray *removeViews = [NSMutableArray array];
    for (UIView *view in self.visibleViews) {
        if (![newVisibleLsvIds containsObject:view.lsvId]) {
            [removeViews addObject:view];
        }
    }
    for (UIView *view in removeViews) {
        [self.visibleViews removeObject:view];
        [self enqueueReusableView:view];
        [view removeFromSuperview];
    }
Copy the code

The original link

The Comprehensive Calculator is a versatile calculator that can calculate mortgage, personal income tax, year-end bonus, interest, BMI and small and large amounts of money. No need to download multiple calculators to find. Also support real – time update loan rates oh ~.