在实际项目中你或许会遇到在一个集合视图中移动一项到另外一个位置,那么此时我们需要对视图中的元素进行重新排序,今天推荐一个很好用的第三方类LXReorderableCollectionViewFlowLayout【点此链接进入GITHUB

下面附上实现代码

//
// LXReorderableCollectionViewFlowLayout.h
//
// Created by Stan Chang Khin Boon on 1/10/12.
// Copyright (c) 2012 d--buzz. All rights reserved.
// #import <UIKit/UIKit.h> @interface LXReorderableCollectionViewFlowLayout : UICollectionViewFlowLayout <UIGestureRecognizerDelegate> @property (assign, nonatomic) CGFloat scrollingSpeed;
@property (assign, nonatomic) UIEdgeInsets scrollingTriggerEdgeInsets;
@property (strong, nonatomic, readonly) UILongPressGestureRecognizer *longPressGestureRecognizer;
@property (strong, nonatomic, readonly) UIPanGestureRecognizer *panGestureRecognizer; - (void)setUpGestureRecognizersOnCollectionView __attribute__((deprecated("Calls to setUpGestureRecognizersOnCollectionView method are not longer needed as setup are done automatically through KVO."))); @end @protocol LXReorderableCollectionViewDataSource <UICollectionViewDataSource> @optional - (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath willMoveToIndexPath:(NSIndexPath *)toIndexPath;
- (void)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath didMoveToIndexPath:(NSIndexPath *)toIndexPath; - (BOOL)collectionView:(UICollectionView *)collectionView canMoveItemAtIndexPath:(NSIndexPath *)indexPath;
- (BOOL)collectionView:(UICollectionView *)collectionView itemAtIndexPath:(NSIndexPath *)fromIndexPath canMoveToIndexPath:(NSIndexPath *)toIndexPath; @end @protocol LXReorderableCollectionViewDelegateFlowLayout <UICollectionViewDelegateFlowLayout>
@optional - (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout willBeginDraggingItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout didBeginDraggingItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout willEndDraggingItemAtIndexPath:(NSIndexPath *)indexPath;
- (void)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout didEndDraggingItemAtIndexPath:(NSIndexPath *)indexPath; @end

LXReorderableCollectionViewFlowLayout.h

//
// LXReorderableCollectionViewFlowLayout.m
//
// Created by Stan Chang Khin Boon on 1/10/12.
// Copyright (c) 2012 d--buzz. All rights reserved.
// #import "LXReorderableCollectionViewFlowLayout.h"
#import <QuartzCore/QuartzCore.h>
#import <objc/runtime.h> #define LX_FRAMES_PER_SECOND 60.0 #ifndef CGGEOMETRY_LXSUPPORT_H_
CG_INLINE CGPoint
LXS_CGPointAdd(CGPoint point1, CGPoint point2) {
return CGPointMake(point1.x + point2.x, point1.y + point2.y);
}
#endif typedef NS_ENUM(NSInteger, LXScrollingDirection) {
LXScrollingDirectionUnknown = ,
LXScrollingDirectionUp,
LXScrollingDirectionDown,
LXScrollingDirectionLeft,
LXScrollingDirectionRight
}; static NSString * const kLXScrollingDirectionKey = @"LXScrollingDirection";
static NSString * const kLXCollectionViewKeyPath = @"collectionView"; @interface CADisplayLink (LX_userInfo)
@property (nonatomic, copy) NSDictionary *LX_userInfo;
@end @implementation CADisplayLink (LX_userInfo)
- (void) setLX_userInfo:(NSDictionary *) LX_userInfo {
objc_setAssociatedObject(self, "LX_userInfo", LX_userInfo, OBJC_ASSOCIATION_COPY);
} - (NSDictionary *) LX_userInfo {
return objc_getAssociatedObject(self, "LX_userInfo");
}
@end @interface UICollectionViewCell (LXReorderableCollectionViewFlowLayout) - (UIImage *)LX_rasterizedImage; @end @implementation UICollectionViewCell (LXReorderableCollectionViewFlowLayout) - (UIImage *)LX_rasterizedImage {
UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 0.0f);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
} @end @interface LXReorderableCollectionViewFlowLayout () @property (strong, nonatomic) NSIndexPath *selectedItemIndexPath;
@property (strong, nonatomic) UIView *currentView;
@property (assign, nonatomic) CGPoint currentViewCenter;
@property (assign, nonatomic) CGPoint panTranslationInCollectionView;
@property (strong, nonatomic) CADisplayLink *displayLink; @property (assign, nonatomic, readonly) id<LXReorderableCollectionViewDataSource> dataSource;
@property (assign, nonatomic, readonly) id<LXReorderableCollectionViewDelegateFlowLayout> delegate; @end @implementation LXReorderableCollectionViewFlowLayout - (void)setDefaults {
_scrollingSpeed = 300.0f;
_scrollingTriggerEdgeInsets = UIEdgeInsetsMake(50.0f, 50.0f, 50.0f, 50.0f);
} - (void)setupCollectionView {
_longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self
action:@selector(handleLongPressGesture:)];
_longPressGestureRecognizer.delegate = self; // Links the default long press gesture recognizer to the custom long press gesture recognizer we are creating now
// by enforcing failure dependency so that they doesn't clash.
for (UIGestureRecognizer *gestureRecognizer in self.collectionView.gestureRecognizers) {
if ([gestureRecognizer isKindOfClass:[UILongPressGestureRecognizer class]]) {
[gestureRecognizer requireGestureRecognizerToFail:_longPressGestureRecognizer];
}
} [self.collectionView addGestureRecognizer:_longPressGestureRecognizer]; _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self
action:@selector(handlePanGesture:)];
_panGestureRecognizer.delegate = self;
[self.collectionView addGestureRecognizer:_panGestureRecognizer]; // Useful in multiple scenarios: one common scenario being when the Notification Center drawer is pulled down
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleApplicationWillResignActive:) name: UIApplicationWillResignActiveNotification object:nil];
} - (id)init {
self = [super init];
if (self) {
[self setDefaults];
[self addObserver:self forKeyPath:kLXCollectionViewKeyPath options:NSKeyValueObservingOptionNew context:nil];
}
return self;
} - (id)initWithCoder:(NSCoder *)aDecoder {
self = [super initWithCoder:aDecoder];
if (self) {
[self setDefaults];
[self addObserver:self forKeyPath:kLXCollectionViewKeyPath options:NSKeyValueObservingOptionNew context:nil];
}
return self;
} - (void)dealloc {
[self invalidatesScrollTimer];
[self removeObserver:self forKeyPath:kLXCollectionViewKeyPath];
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationWillResignActiveNotification object:nil];
} - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes {
if ([layoutAttributes.indexPath isEqual:self.selectedItemIndexPath]) {
layoutAttributes.hidden = YES;
}
} - (id<LXReorderableCollectionViewDataSource>)dataSource {
return (id<LXReorderableCollectionViewDataSource>)self.collectionView.dataSource;
} - (id<LXReorderableCollectionViewDelegateFlowLayout>)delegate {
return (id<LXReorderableCollectionViewDelegateFlowLayout>)self.collectionView.delegate;
} - (void)invalidateLayoutIfNecessary {
NSIndexPath *newIndexPath = [self.collectionView indexPathForItemAtPoint:self.currentView.center];
NSIndexPath *previousIndexPath = self.selectedItemIndexPath; if ((newIndexPath == nil) || [newIndexPath isEqual:previousIndexPath]) {
return;
} if ([self.dataSource respondsToSelector:@selector(collectionView:itemAtIndexPath:canMoveToIndexPath:)] &&
![self.dataSource collectionView:self.collectionView itemAtIndexPath:previousIndexPath canMoveToIndexPath:newIndexPath]) {
return;
} self.selectedItemIndexPath = newIndexPath; if ([self.dataSource respondsToSelector:@selector(collectionView:itemAtIndexPath:willMoveToIndexPath:)]) {
[self.dataSource collectionView:self.collectionView itemAtIndexPath:previousIndexPath willMoveToIndexPath:newIndexPath];
} __weak typeof(self) weakSelf = self;
[self.collectionView performBatchUpdates:^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.collectionView deleteItemsAtIndexPaths:@[ previousIndexPath ]];
[strongSelf.collectionView insertItemsAtIndexPaths:@[ newIndexPath ]];
}
} completion:^(BOOL finished) {
__strong typeof(self) strongSelf = weakSelf;
if ([strongSelf.dataSource respondsToSelector:@selector(collectionView:itemAtIndexPath:didMoveToIndexPath:)]) {
[strongSelf.dataSource collectionView:strongSelf.collectionView itemAtIndexPath:previousIndexPath didMoveToIndexPath:newIndexPath];
}
}];
} - (void)invalidatesScrollTimer {
if (!self.displayLink.paused) {
[self.displayLink invalidate];
}
self.displayLink = nil;
} - (void)setupScrollTimerInDirection:(LXScrollingDirection)direction {
if (!self.displayLink.paused) {
LXScrollingDirection oldDirection = [self.displayLink.LX_userInfo[kLXScrollingDirectionKey] integerValue]; if (direction == oldDirection) {
return;
}
} [self invalidatesScrollTimer]; self.displayLink = [CADisplayLink displayLinkWithTarget:self selector:@selector(handleScroll:)];
self.displayLink.LX_userInfo = @{ kLXScrollingDirectionKey : @(direction) }; [self.displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
} #pragma mark - Target/Action methods // Tight loop, allocate memory sparely, even if they are stack allocation.
- (void)handleScroll:(CADisplayLink *)displayLink {
LXScrollingDirection direction = (LXScrollingDirection)[displayLink.LX_userInfo[kLXScrollingDirectionKey] integerValue];
if (direction == LXScrollingDirectionUnknown) {
return;
} CGSize frameSize = self.collectionView.bounds.size;
CGSize contentSize = self.collectionView.contentSize;
CGPoint contentOffset = self.collectionView.contentOffset;
UIEdgeInsets contentInset = self.collectionView.contentInset;
// Important to have an integer `distance` as the `contentOffset` property automatically gets rounded
// and it would diverge from the view's center resulting in a "cell is slipping away under finger"-bug.
CGFloat distance = rint(self.scrollingSpeed / LX_FRAMES_PER_SECOND);
CGPoint translation = CGPointZero; switch(direction) {
case LXScrollingDirectionUp: {
distance = -distance;
CGFloat minY = 0.0f - contentInset.top; if ((contentOffset.y + distance) <= minY) {
distance = -contentOffset.y - contentInset.top;
} translation = CGPointMake(0.0f, distance);
} break;
case LXScrollingDirectionDown: {
CGFloat maxY = MAX(contentSize.height, frameSize.height) - frameSize.height + contentInset.bottom; if ((contentOffset.y + distance) >= maxY) {
distance = maxY - contentOffset.y;
} translation = CGPointMake(0.0f, distance);
} break;
case LXScrollingDirectionLeft: {
distance = -distance;
CGFloat minX = 0.0f - contentInset.left; if ((contentOffset.x + distance) <= minX) {
distance = -contentOffset.x - contentInset.left;
} translation = CGPointMake(distance, 0.0f);
} break;
case LXScrollingDirectionRight: {
CGFloat maxX = MAX(contentSize.width, frameSize.width) - frameSize.width + contentInset.right; if ((contentOffset.x + distance) >= maxX) {
distance = maxX - contentOffset.x;
} translation = CGPointMake(distance, 0.0f);
} break;
default: {
// Do nothing...
} break;
} self.currentViewCenter = LXS_CGPointAdd(self.currentViewCenter, translation);
self.currentView.center = LXS_CGPointAdd(self.currentViewCenter, self.panTranslationInCollectionView);
self.collectionView.contentOffset = LXS_CGPointAdd(contentOffset, translation);
} - (void)handleLongPressGesture:(UILongPressGestureRecognizer *)gestureRecognizer {
switch(gestureRecognizer.state) {
case UIGestureRecognizerStateBegan: {
NSIndexPath *currentIndexPath = [self.collectionView indexPathForItemAtPoint:[gestureRecognizer locationInView:self.collectionView]]; if ([self.dataSource respondsToSelector:@selector(collectionView:canMoveItemAtIndexPath:)] &&
![self.dataSource collectionView:self.collectionView canMoveItemAtIndexPath:currentIndexPath]) {
return;
} self.selectedItemIndexPath = currentIndexPath; if ([self.delegate respondsToSelector:@selector(collectionView:layout:willBeginDraggingItemAtIndexPath:)]) {
[self.delegate collectionView:self.collectionView layout:self willBeginDraggingItemAtIndexPath:self.selectedItemIndexPath];
} UICollectionViewCell *collectionViewCell = [self.collectionView cellForItemAtIndexPath:self.selectedItemIndexPath]; self.currentView = [[UIView alloc] initWithFrame:collectionViewCell.frame]; collectionViewCell.highlighted = YES;
UIImageView *highlightedImageView = [[UIImageView alloc] initWithImage:[collectionViewCell LX_rasterizedImage]];
highlightedImageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
highlightedImageView.alpha = 1.0f; collectionViewCell.highlighted = NO;
UIImageView *imageView = [[UIImageView alloc] initWithImage:[collectionViewCell LX_rasterizedImage]];
imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
imageView.alpha = 0.0f; [self.currentView addSubview:imageView];
[self.currentView addSubview:highlightedImageView];
[self.collectionView addSubview:self.currentView]; self.currentViewCenter = self.currentView.center; __weak typeof(self) weakSelf = self;
[UIView
animateWithDuration:0.3
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
strongSelf.currentView.transform = CGAffineTransformMakeScale(1.1f, 1.1f);
highlightedImageView.alpha = 0.0f;
imageView.alpha = 1.0f;
}
}
completion:^(BOOL finished) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[highlightedImageView removeFromSuperview]; if ([strongSelf.delegate respondsToSelector:@selector(collectionView:layout:didBeginDraggingItemAtIndexPath:)]) {
[strongSelf.delegate collectionView:strongSelf.collectionView layout:strongSelf didBeginDraggingItemAtIndexPath:strongSelf.selectedItemIndexPath];
}
}
}]; [self invalidateLayout];
} break;
case UIGestureRecognizerStateCancelled:
case UIGestureRecognizerStateEnded: {
NSIndexPath *currentIndexPath = self.selectedItemIndexPath; if (currentIndexPath) {
if ([self.delegate respondsToSelector:@selector(collectionView:layout:willEndDraggingItemAtIndexPath:)]) {
[self.delegate collectionView:self.collectionView layout:self willEndDraggingItemAtIndexPath:currentIndexPath];
} self.selectedItemIndexPath = nil;
self.currentViewCenter = CGPointZero; UICollectionViewLayoutAttributes *layoutAttributes = [self layoutAttributesForItemAtIndexPath:currentIndexPath]; __weak typeof(self) weakSelf = self;
[UIView
animateWithDuration:0.3
delay:0.0
options:UIViewAnimationOptionBeginFromCurrentState
animations:^{
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
strongSelf.currentView.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
strongSelf.currentView.center = layoutAttributes.center;
}
}
completion:^(BOOL finished) {
__strong typeof(self) strongSelf = weakSelf;
if (strongSelf) {
[strongSelf.currentView removeFromSuperview];
strongSelf.currentView = nil;
[strongSelf invalidateLayout]; if ([strongSelf.delegate respondsToSelector:@selector(collectionView:layout:didEndDraggingItemAtIndexPath:)]) {
[strongSelf.delegate collectionView:strongSelf.collectionView layout:strongSelf didEndDraggingItemAtIndexPath:currentIndexPath];
}
}
}];
}
} break; default: break;
}
} - (void)handlePanGesture:(UIPanGestureRecognizer *)gestureRecognizer {
switch (gestureRecognizer.state) {
case UIGestureRecognizerStateBegan:
case UIGestureRecognizerStateChanged: {
self.panTranslationInCollectionView = [gestureRecognizer translationInView:self.collectionView];
CGPoint viewCenter = self.currentView.center = LXS_CGPointAdd(self.currentViewCenter, self.panTranslationInCollectionView); [self invalidateLayoutIfNecessary]; switch (self.scrollDirection) {
case UICollectionViewScrollDirectionVertical: {
if (viewCenter.y < (CGRectGetMinY(self.collectionView.bounds) + self.scrollingTriggerEdgeInsets.top)) {
[self setupScrollTimerInDirection:LXScrollingDirectionUp];
} else {
if (viewCenter.y > (CGRectGetMaxY(self.collectionView.bounds) - self.scrollingTriggerEdgeInsets.bottom)) {
[self setupScrollTimerInDirection:LXScrollingDirectionDown];
} else {
[self invalidatesScrollTimer];
}
}
} break;
case UICollectionViewScrollDirectionHorizontal: {
if (viewCenter.x < (CGRectGetMinX(self.collectionView.bounds) + self.scrollingTriggerEdgeInsets.left)) {
[self setupScrollTimerInDirection:LXScrollingDirectionLeft];
} else {
if (viewCenter.x > (CGRectGetMaxX(self.collectionView.bounds) - self.scrollingTriggerEdgeInsets.right)) {
[self setupScrollTimerInDirection:LXScrollingDirectionRight];
} else {
[self invalidatesScrollTimer];
}
}
} break;
}
} break;
case UIGestureRecognizerStateCancelled:
case UIGestureRecognizerStateEnded: {
[self invalidatesScrollTimer];
} break;
default: {
// Do nothing...
} break;
}
} #pragma mark - UICollectionViewLayout overridden methods - (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *layoutAttributesForElementsInRect = [super layoutAttributesForElementsInRect:rect]; for (UICollectionViewLayoutAttributes *layoutAttributes in layoutAttributesForElementsInRect) {
switch (layoutAttributes.representedElementCategory) {
case UICollectionElementCategoryCell: {
[self applyLayoutAttributes:layoutAttributes];
} break;
default: {
// Do nothing...
} break;
}
} return layoutAttributesForElementsInRect;
} - (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath {
UICollectionViewLayoutAttributes *layoutAttributes = [super layoutAttributesForItemAtIndexPath:indexPath]; switch (layoutAttributes.representedElementCategory) {
case UICollectionElementCategoryCell: {
[self applyLayoutAttributes:layoutAttributes];
} break;
default: {
// Do nothing...
} break;
} return layoutAttributes;
} #pragma mark - UIGestureRecognizerDelegate methods - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([self.panGestureRecognizer isEqual:gestureRecognizer]) {
return (self.selectedItemIndexPath != nil);
}
return YES;
} - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
if ([self.longPressGestureRecognizer isEqual:gestureRecognizer]) {
return [self.panGestureRecognizer isEqual:otherGestureRecognizer];
} if ([self.panGestureRecognizer isEqual:gestureRecognizer]) {
return [self.longPressGestureRecognizer isEqual:otherGestureRecognizer];
} return NO;
} #pragma mark - Key-Value Observing methods - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
if ([keyPath isEqualToString:kLXCollectionViewKeyPath]) {
if (self.collectionView != nil) {
[self setupCollectionView];
} else {
[self invalidatesScrollTimer];
}
}
} #pragma mark - Notifications - (void)handleApplicationWillResignActive:(NSNotification *)notification {
self.panGestureRecognizer.enabled = NO;
self.panGestureRecognizer.enabled = YES;
} #pragma mark - Depreciated methods #pragma mark Starting from 0.1.0
- (void)setUpGestureRecognizersOnCollectionView {
// Do nothing...
} @end

LXReorderableCollectionViewFlowLayout.m

效果

    

【推荐】iOS集合视图的可重新排序的layout的更多相关文章

  1. iOS集合视图单元格高亮和选中的区别

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 免责申明:本博客提供的所有翻译文章原稿均来自互联网,仅供学习交 ...

  2. 集合视图控制器(CollectionViewController) 、 标签控制器(TabBarController) 、 高级控件介绍

    1 创建集合视图,设置相关属性以满足要求 1.1 问题 集合视图控制器UIConllectionViewController是一个展示大量数据的控制器,系统默认管理着一个集合视图UICollectio ...

  3. iOS:集合视图UICollectionView、集合视图控制器UICollectionViewController、集合视图单元格UICollectionViewCell(创建表格的另一种控件)

    两种创建表格方式的比较:表格视图.集合视图(二者十分类似) <1>相同点:   表格视图:UITableView(位于storyboard中,通过UIViewController控制器实现 ...

  4. 集合视图UICollectionView 介绍及其示例程序

    UICollectionView是一种新的数据展示方式,简单来说可以把它理解成多列的UITableView.如果你用过iBooks的话,可 能你还对书架布局有一定印象,一个虚拟书架上放着你下载和购买的 ...

  5. UICollectionView(集合视图)以及自定义集合视图

    一.UICollectionView集合视图           其继承自UIScrollView.         UICollectionView类是iOS6新引进的API,用于展示集合视图,布局 ...

  6. UICollectionView集合视图的概念

    如何创建UICollectionView 集合视图的布局UICollectionViewFlowLayout 自定义cell 布局协议UICollectionViewDelegateFlowLayou ...

  7. swift:创建集合视图UICollectionView

    swift中创建集合视图和OC中差不多,主要是实现UICollectionViewDataSource数据源协议和UICollectionViewDelegateFlowLayout自定义布局协议,其 ...

  8. UICollectionView 集合视图用法,自定义Cell

    在View里面 //1.创建UICollectionViewFlowLayout UICollectionViewFlowLayout *flowLayout=[[UICollectionViewFl ...

  9. iOS 让视图UIView单独显示某一侧的边框线

    iOS 让视图UIView 单独显示某一侧的边框线   有时候需要让view显示某一侧的边框线,这时设置layer的border是达不到效果的.在网上查阅资料发现有一个投机取巧的办法,原理是给view ...

随机推荐

  1. 分享自己写的一个小工具RGB转十六进制(高手勿喷)

    由于工作经常美工给的颜色是rgb,而我们网页里面是16进制.网上也有很多类型的工具.不过似乎都用浏览器打开.没网就不爽了 实现也很简单.代码已经共享了 http://git.oschina.net/w ...

  2. WPF UI虚拟化

    ComboBox

  3. Atlas+Keepalived系列二:管理Atlas

    1:登录代理端口1234 [root@localhost bin]# mysql -uroot -p -P1234 -h127.0.0.1 proxy-address项配置,例如proxy-addre ...

  4. Intellij IDEA 配置Subversion插件

    在使用Intellij的过程中,突然发现svn不起效了,在VCS–>Checkout from Version Control中也未发现Subversion这一项.如下图: 一.原因查找 经过分 ...

  5. GoldenGate 配置extract,replicat进程自启动

    在GoldenGate中主进程是manager进程,使用start mgr启动.可以在mgr进程中添加一些参数用来在启动mgr进程的同时启动extract和replicat进程 GGSCI (gg01 ...

  6. Android Multiple Screens Android 屏幕适配的一些总结

    作为一名Android应用开发程序猿,最痛苦的事莫过于在屏幕适配了,这与历史原因有关,具体就不深究了. 直到最近才搞明白dpi是怎么换算的,在开发的过程中,一个应用运行的屏幕标准应该是分辨率为320x ...

  7. D3 & Data Visualization in Ext JS

    通过适配器可以在ExtJs中轻松的集成D3的展示能力 http://video.sencha.com/watch/zvUjnFJ91xVvuwdTh2zjqP?mkt_tok=eyJpIjoiWm1a ...

  8. Pro ASP.NET MVC –第五章 使用Razor

    Razor是微软在MVC3中引入的视图引擎的名字,在MVC4中对其进行了改进(尽管改动非常小).视图引擎处理ASP.NET内容.寻找指令,典型地用于插入动态数据并输出到浏览器中.微软维持了两个视图引擎 ...

  9. mysql用shell建100多字段表并导入

    excel列超过160多个,导入时报错,把excel第一行另存为逗号分隔的csv文件,用shell建表 vim createTable.sh #!/bin/sh str="CA6430M,H ...

  10. 结合使用saiku、mondrian workbentch建立多维查询报表

    1.简介 前几篇博客已经介绍了saiku.mondrian.MDX和模式文件他们之间的关系,那么如何将它们串联起来,供产品人员使用哪?下面咱们一步一步的实现 2.建立数据表 建表语句参考:http:/ ...