[翻译] VLDContextSheet

VLDContextSheet

效果:

A clone of the Pinterest iOS app context menu.

复制了Pinterest应用的菜单效果。

Example Usage - 使用样例

VLDContextSheetItem *item1 = [[VLDContextSheetItem alloc] initWithTitle: @"Gift"
                                                                  image: [UIImage imageNamed: @"gift"]
                                                       highlightedImage: [UIImage imageNamed: @"gift_highlighted"]];

VLDContextSheetItem *item2 = ...

VLDContextSheetItem *item3 = ...

self.contextSheet = [[VLDContextSheet alloc] initWithItems: @[ item1, item2, item3 ]];
self.contextSheet.delegate = self;

Show - 显示

- (void) longPressed: (UIGestureRecognizer *) gestureRecognizer {
    if(gestureRecognizer.state == UIGestureRecognizerStateBegan) {

        [self.contextSheet startWithGestureRecognizer: gestureRecognizer
                                               inView: self.view];
    }
}

Delegate method - 代理方法

- (void) contextSheet: (VLDContextSheet *) contextSheet didSelectItem: (VLDContextSheetItem *) item {
    NSLog(@"Selected item: %@", item.title);
}

Hide - 隐藏

[self.contextSheet end];

For more info check the Example project.

你可以在示例代码里面查看更多的信息。

附录源码:

VLDContextSheetItem.h 与 VLDContextSheetItem.m

//
//  VLDContextSheetItem.h
//
//  Created by Vladimir Angelov on 2/10/14.
//  Copyright (c) 2014 Vladimir Angelov. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface VLDContextSheetItem : NSObject

- (id) initWithTitle: (NSString *) title
               image: (UIImage *) image
    highlightedImage: (UIImage *) highlightedImage;

@property (strong, readonly) NSString *title;
@property (strong, readonly) UIImage *image;
@property (strong, readonly) UIImage *highlightedImage;

@property (assign, readwrite, getter = isEnabled) BOOL enabled;

@end
//
//  VLDContextSheetItem.m
//
//  Created by Vladimir Angelov on 2/10/14.
//  Copyright (c) 2014 Vladimir Angelov. All rights reserved.
//

#import "VLDContextSheetItem.h"

@implementation VLDContextSheetItem

- (id) initWithTitle: (NSString *) title
               image: (UIImage *) image
    highlightedImage: (UIImage *) highlightedImage {

    self = [super init];

    if(self) {
        _title = title;
        _image = image;
        _highlightedImage = highlightedImage;
        _enabled = YES;
    }

    return self;
}

@end

VLDContextSheetItem.h 与 VLDContextSheetItem.m

//
//  VLDContextSheetItem.h
//
//  Created by Vladimir Angelov on 2/9/14.
//  Copyright (c) 2014 Vladimir Angelov. All rights reserved.
//

#import <Foundation/Foundation.h>

@class VLDContextSheetItem;

@interface VLDContextSheetItemView : UIView

@property (strong, nonatomic) VLDContextSheetItem *item;
@property (readonly) BOOL isHighlighted;

- (void) setHighlighted: (BOOL) highlighted animated: (BOOL) animated;

@end
//
//  VLDContextSheetItemView.m,
//
//  Created by Vladimir Angelov on 2/9/14.
//  Copyright (c) 2014 Vladimir Angelov. All rights reserved.
//

#import "VLDContextSheetItemView.h"
#import "VLDContextSheetItem.h"

#import <CoreImage/CoreImage.h>

static const NSInteger VLDTextPadding = 5;

@interface VLDContextSheetItemView ()

@property (nonatomic, strong) UIImageView *imageView;
@property (nonatomic, strong) UIImageView *highlightedImageView;
@property (nonatomic, strong) UILabel *label;
@property (nonatomic, assign) NSInteger labelWidth;

@end

@implementation VLDContextSheetItemView

@synthesize item = _item;

- (id) initWithFrame: (CGRect) frame {
    self = [super initWithFrame: CGRectMake(0, 0, 50, 83)];

    if(self) {
        [self createSubviews];
    }

    return self;
}

- (void) createSubviews {
    _imageView = [[UIImageView alloc] init];
    [self addSubview: _imageView];

    _highlightedImageView = [[UIImageView alloc] init];
    _highlightedImageView.alpha = 0.0;
    [self addSubview: _highlightedImageView];

    _label = [[UILabel alloc] init];
    _label.clipsToBounds = YES;
    _label.font = [UIFont systemFontOfSize: 10];
    _label.textAlignment = NSTextAlignmentCenter;
    _label.layer.cornerRadius = 7;
    _label.backgroundColor = [UIColor colorWithWhite: 0.0 alpha: 0.4];
    _label.textColor = [UIColor whiteColor];
    _label.alpha = 0.0;
    [self addSubview: _label];
}

- (void) layoutSubviews {
    [super layoutSubviews];

    self.imageView.frame = CGRectMake(0, (self.frame.size.height - self.frame.size.width) / 2, self.frame.size.width, self.frame.size.width);
    self.highlightedImageView.frame = self.imageView.frame;
    self.label.frame = CGRectMake((self.frame.size.width - self.labelWidth) / 2.0, 0, self.labelWidth, 14);
}

- (void) setItem:(VLDContextSheetItem *)item {
    _item = item;

    [self updateImages];
    [self updateLabelText];
}

- (void) updateImages {
    self.imageView.image = self.item.image;
    self.highlightedImageView.image = self.item.highlightedImage;

    self.imageView.alpha = self.item.isEnabled ? 1.0 : 0.3;
}

- (void) updateLabelText {
    self.label.text = self.item.title;
    self.labelWidth = 2 * VLDTextPadding + ceil([self.label.text sizeWithAttributes: @{ NSFontAttributeName: self.label.font }].width);
    [self setNeedsDisplay];
}

- (void) setHighlighted: (BOOL) highlighted animated: (BOOL) animated {
    if (!self.item.isEnabled) {
        return;
    }

    _isHighlighted = highlighted;

    [UIView animateWithDuration: animated ? 0.3 : 0.0
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         self.highlightedImageView.alpha = (highlighted ? 1.0 : 0.0);
                         self.imageView.alpha = 1 - self.highlightedImageView.alpha;
                         self.label.alpha = self.highlightedImageView.alpha;

                     }
                     completion: nil];

}

@end

VLDContextSheet.h 与 VLDContextSheet.m

//
//  VLDContextSheet.h
//
//  Created by Vladimir Angelov on 2/7/14.
//  Copyright (c) 2014 Vladimir Angelov. All rights reserved.
//

#import <Foundation/Foundation.h>

@class VLDContextSheet;
@class VLDContextSheetItem;

@protocol VLDContextSheetDelegate <NSObject>

- (void) contextSheet: (VLDContextSheet *) contextSheet didSelectItem: (VLDContextSheetItem *) item;

@end

@interface VLDContextSheet : UIView

@property (assign, nonatomic) NSInteger radius;
@property (assign, nonatomic) CGFloat rotation;
@property (assign, nonatomic) CGFloat rangeAngle;
@property (strong, nonatomic) NSArray *items;
@property (assign, nonatomic) id<VLDContextSheetDelegate> delegate;

- (id) initWithItems: (NSArray *) items;

- (void) startWithGestureRecognizer: (UIGestureRecognizer *) gestureRecognizer
                             inView: (UIView *) view;
- (void) end;

@end
//
//  VLDContextSheet.m
//
//  Created by Vladimir Angelov on 2/7/14.
//  Copyright (c) 2014 Vladimir Angelov. All rights reserved.
//

#import "VLDContextSheetItemView.h"
#import "VLDContextSheet.h"

typedef struct {
    CGRect rect;
    CGFloat rotation;
} VLDZone;

static const NSInteger VLDMaxTouchDistanceAllowance = 40;
static const NSInteger VLDZonesCount = 10;

static inline VLDZone VLDZoneMake(CGRect rect, CGFloat rotation) {
    VLDZone zone;

    zone.rect = rect;
    zone.rotation = rotation;

    return zone;
}

static CGFloat VLDVectorDotProduct(CGPoint vector1, CGPoint vector2) {
    return vector1.x * vector2.x + vector1.y * vector2.y;
}

static CGFloat VLDVectorLength(CGPoint vector) {
    return sqrt(vector.x * vector.x + vector.y * vector.y);
}

static CGRect VLDOrientedScreenBounds() {
    CGRect bounds = [UIScreen mainScreen].bounds;

    if(UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation) &&
        bounds.size.width < bounds.size.height) {

        bounds.size = CGSizeMake(bounds.size.height, bounds.size.width);
    }

    return bounds;
}

@interface VLDContextSheet ()

@property (strong, nonatomic) NSArray *itemViews;
@property (strong, nonatomic) UIView *centerView;
@property (strong, nonatomic) UIView *backgroundView;
@property (strong, nonatomic) VLDContextSheetItemView *selectedItemView;
@property (assign, nonatomic) BOOL openAnimationFinished;
@property (assign, nonatomic) CGPoint touchCenter;
@property (strong, nonatomic) UIGestureRecognizer *starterGestureRecognizer;

@end

@implementation VLDContextSheet {

    VLDZone zones[VLDZonesCount];
}

- (id) initWithFrame: (CGRect) frame {
    return [self initWithItems: nil];
}

- (id) initWithItems: (NSArray *) items {
    self = [super initWithFrame: VLDOrientedScreenBounds()];

    if(self) {
        _items = items;
        _radius = 100;
        _rangeAngle = M_PI / 1.6;

        [self createSubviews];
    }

    return self;
}

- (void) dealloc {
    [self.starterGestureRecognizer removeTarget: self action: @selector(gestureRecognizedStateObserver:)];
}

- (void) createSubviews {
    _backgroundView = [[UIView alloc] initWithFrame: CGRectZero];
    _backgroundView.backgroundColor = [UIColor colorWithWhite: 0 alpha: 0.6];
    [self addSubview: self.backgroundView];

    _itemViews = [[NSMutableArray alloc] init];

    for(VLDContextSheetItem *item in _items) {
        VLDContextSheetItemView *itemView = [[VLDContextSheetItemView alloc] init];
        itemView.item = item;

        [self addSubview: itemView];
        [(NSMutableArray *) _itemViews addObject: itemView];
    }

    VLDContextSheetItemView *sampleItemView = _itemViews[0];

    _centerView = [[UIView alloc] initWithFrame: CGRectMake(0, 0, sampleItemView.frame.size.width, sampleItemView.frame.size.width)];
    _centerView.layer.cornerRadius = 25;
    _centerView.layer.borderWidth = 2;
    _centerView.layer.borderColor = [UIColor grayColor].CGColor;
    [self addSubview: _centerView];

}

- (void) layoutSubviews {
    [super layoutSubviews];

    self.backgroundView.frame = self.bounds;
}

- (void) setCenterViewHighlighted: (BOOL) highlighted {
    _centerView.backgroundColor = highlighted ? [UIColor colorWithWhite: 0.5 alpha: 0.4] : nil;
}

- (void) createZones {
    CGRect screenRect = self.bounds;

    NSInteger rowHeight1 = 120;

    zones[0] = VLDZoneMake(CGRectMake(0, 0, 70, rowHeight1), 0.8);
    zones[1] = VLDZoneMake(CGRectMake(zones[0].rect.size.width, 0, 40, rowHeight1), 0.4);

    zones[2] = VLDZoneMake(CGRectMake(zones[1].rect.origin.x + zones[1].rect.size.width, 0, screenRect.size.width - 2 *(zones[0].rect.size.width + zones[1].rect.size.width), rowHeight1), 0);

    zones[3] = VLDZoneMake(CGRectMake(zones[2].rect.origin.x + zones[2].rect.size.width, 0, zones[1].rect.size.width, rowHeight1),  -zones[1].rotation);
    zones[4] = VLDZoneMake(CGRectMake(zones[3].rect.origin.x + zones[3].rect.size.width, 0, zones[0].rect.size.width, rowHeight1), -zones[0].rotation);

    NSInteger rowHeight2 = screenRect.size.height - zones[0].rect.size.height;

    zones[5] = VLDZoneMake(CGRectMake(0, zones[0].rect.size.height, zones[0].rect.size.width, rowHeight2), M_PI - zones[0].rotation);
    zones[6] = VLDZoneMake(CGRectMake(zones[5].rect.size.width, zones[5].rect.origin.y, zones[1].rect.size.width, rowHeight2), M_PI - zones[1].rotation);
    zones[7] = VLDZoneMake(CGRectMake(zones[6].rect.origin.x + zones[6].rect.size.width, zones[5].rect.origin.y, zones[2].rect.size.width, rowHeight2), M_PI - zones[2].rotation);
    zones[8] = VLDZoneMake(CGRectMake(zones[7].rect.origin.x + zones[7].rect.size.width, zones[5].rect.origin.y, zones[3].rect.size.width, rowHeight2), M_PI - zones[3].rotation);
    zones[9] = VLDZoneMake(CGRectMake(zones[8].rect.origin.x + zones[8].rect.size.width, zones[5].rect.origin.y, zones[4].rect.size.width, rowHeight2), M_PI - zones[4].rotation);
}

/* Only used for testing the touch zones */
- (void) drawZones {
    for(int i = 0; i < VLDZonesCount; i++) {
        UIView *zoneView = [[UIView alloc] initWithFrame: zones[i].rect];

        CGFloat hue = ( arc4random() % 256 / 256.0 );
        CGFloat saturation = ( arc4random() % 128 / 256.0 ) + 0.5;
        CGFloat brightness = ( arc4random() % 128 / 256.0 ) + 0.5;
        UIColor *color = [UIColor colorWithHue:hue saturation:saturation brightness:brightness alpha:1];

        zoneView.backgroundColor = color;
        [self addSubview: zoneView];
    }
}

- (void) updateItemView: (UIView *) itemView
          touchDistance: (CGFloat) touchDistance
               animated: (BOOL) animated  {

    if(!animated) {
        [self updateItemViewNotAnimated: itemView touchDistance: touchDistance];
    }
    else  {
        [UIView animateWithDuration: 0.4
                              delay: 0
             usingSpringWithDamping: 0.45
              initialSpringVelocity: 7.5
                            options: UIViewAnimationOptionBeginFromCurrentState
                         animations: ^{
                             [self updateItemViewNotAnimated: itemView
                                               touchDistance: touchDistance];
                         }
                         completion: nil];
    }
}

- (void) updateItemViewNotAnimated: (UIView *) itemView touchDistance: (CGFloat) touchDistance  {
    NSInteger itemIndex = [self.itemViews indexOfObject: itemView];
    CGFloat angle = -0.65 + self.rotation + itemIndex * (self.rangeAngle / self.itemViews.count);

    CGFloat resistanceFactor = 1.0 / (touchDistance > 0 ? 6.0 : 3.0);

    itemView.center = CGPointMake(self.touchCenter.x + (self.radius + touchDistance * resistanceFactor) * sin(angle),
                                  self.touchCenter.y + (self.radius + touchDistance * resistanceFactor) * cos(angle));

    CGFloat scale = 1 + 0.2 * (fabs(touchDistance) / self.radius);

    itemView.transform = CGAffineTransformMakeScale(scale, scale);
}

- (void) openItemsFromCenterView {
    self.openAnimationFinished = NO;

    for(int i = 0; i < self.itemViews.count; i++) {
        VLDContextSheetItemView *itemView = self.itemViews[i];
        itemView.transform = CGAffineTransformIdentity;
        itemView.center = self.touchCenter;
        [itemView setHighlighted: NO animated: NO];

        [UIView animateWithDuration: 0.5
                              delay: i * 0.01
             usingSpringWithDamping: 0.45
              initialSpringVelocity: 7.5
                            options: 0
                         animations: ^{
                             [self updateItemViewNotAnimated: itemView touchDistance: 0.0];

                         }
                         completion: ^(BOOL finished) {
                             self.openAnimationFinished = YES;
                         }];
    }
}

- (void) closeItemsToCenterView {
    [UIView animateWithDuration: 0.1
                          delay: 0.0
                        options: UIViewAnimationOptionCurveEaseInOut
                     animations:^{
                         self.alpha = 0.0;
                     }
                     completion:^(BOOL finished) {
                         [self removeFromSuperview];
                         self.alpha = 1.0;
                     }];

}

- (void) startWithGestureRecognizer: (UIGestureRecognizer *) gestureRecognizer inView: (UIView *) view {
    [view addSubview: self];

    self.frame = VLDOrientedScreenBounds();
    [self createZones];

    self.starterGestureRecognizer = gestureRecognizer;

    self.touchCenter = [self.starterGestureRecognizer locationInView: self];
    self.centerView.center = self.touchCenter;
    self.selectedItemView = nil;
    [self setCenterViewHighlighted: YES];
    self.rotation = [self rotationForCenter: self.centerView.center];

    [self openItemsFromCenterView];

    [self.starterGestureRecognizer addTarget: self action: @selector(gestureRecognizedStateObserver:)];
}

- (CGFloat) rotationForCenter: (CGPoint) center {
    for(NSInteger i = 0; i < 10; i++) {
        VLDZone zone = zones[i];

        if(CGRectContainsPoint(zone.rect, center)) {
            return zone.rotation;
        }
    }

    return 0;
}

- (void) gestureRecognizedStateObserver: (UIGestureRecognizer *) gestureRecognizer {
    if(self.openAnimationFinished && gestureRecognizer.state == UIGestureRecognizerStateChanged) {
        CGPoint touchPoint = [gestureRecognizer locationInView: self];

        [self updateItemViewsForTouchPoint: touchPoint];
    }
    else if(gestureRecognizer.state == UIGestureRecognizerStateEnded || gestureRecognizer.state == UIGestureRecognizerStateCancelled) {
        if(gestureRecognizer.state == UIGestureRecognizerStateCancelled) {
            self.selectedItemView = nil;
        }

        [self end];
    }
}

- (CGFloat) signedTouchDistanceForTouchVector: (CGPoint) touchVector itemView: (UIView *) itemView {
    CGFloat touchDistance = VLDVectorLength(touchVector);

    CGPoint oldCenter = itemView.center;
    CGAffineTransform oldTransform = itemView.transform;

    [self updateItemViewNotAnimated: itemView touchDistance: self.radius + 40];

    if(!CGRectContainsRect(self.bounds, itemView.frame)) {
        touchDistance = -touchDistance;
    }

    itemView.center = oldCenter;
    itemView.transform = oldTransform;

    return touchDistance;
}

- (void) updateItemViewsForTouchPoint: (CGPoint) touchPoint {
    CGPoint touchVector = {touchPoint.x - self.touchCenter.x, touchPoint.y - self.touchCenter.y};
    VLDContextSheetItemView *itemView = [self itemViewForTouchVector: touchVector];
    CGFloat touchDistance = [self signedTouchDistanceForTouchVector: touchVector itemView: itemView];

    if(fabs(touchDistance) <= VLDMaxTouchDistanceAllowance) {
        self.centerView.center = CGPointMake(self.touchCenter.x + touchVector.x, self.touchCenter.y + touchVector.y);
        [self setCenterViewHighlighted: YES];
    }
    else {
        [self setCenterViewHighlighted: NO];

        [UIView animateWithDuration: 0.4
                              delay: 0
             usingSpringWithDamping: 0.35
              initialSpringVelocity: 7.5
                            options: UIViewAnimationOptionBeginFromCurrentState
                         animations: ^{
                             self.centerView.center = self.touchCenter;

                         }
                         completion: nil];
    }

    if(touchDistance > self.radius + VLDMaxTouchDistanceAllowance) {
        [itemView setHighlighted: NO animated: YES];

        [self updateItemView: itemView
               touchDistance: 0.0
                    animated: YES];

        self.selectedItemView = nil;

        return;
    }

    if(itemView != self.selectedItemView) {
        [self.selectedItemView setHighlighted: NO animated: YES];

        [self updateItemView: self.selectedItemView
               touchDistance: 0.0
                    animated: YES];

        [self updateItemView: itemView
               touchDistance: touchDistance
                    animated: YES];

        [self bringSubviewToFront: itemView];
    }
    else  {
        [self updateItemView: itemView
               touchDistance: touchDistance
                    animated: NO];
    }

    if(fabs(touchDistance) > VLDMaxTouchDistanceAllowance) {
        [itemView setHighlighted: YES animated: YES];
    }

    self.selectedItemView = itemView;
}

- (VLDContextSheetItemView *) itemViewForTouchVector: (CGPoint) touchVector  {
    CGFloat maxCosOfAngle = -2;
    VLDContextSheetItemView *resultItemView = nil;

    for(int i = 0; i < self.itemViews.count; i++) {
        VLDContextSheetItemView *itemView = self.itemViews[i];
        CGPoint itemViewVector = {
            itemView.center.x - self.touchCenter.x,
            itemView.center.y - self.touchCenter.y
        };

        CGFloat cosOfAngle = VLDVectorDotProduct(itemViewVector, touchVector) / VLDVectorLength(itemViewVector);

        if(cosOfAngle > maxCosOfAngle) {
            maxCosOfAngle = cosOfAngle;
            resultItemView = itemView;
        }
    }

    return resultItemView;
}

- (void) end {
    [self.starterGestureRecognizer removeTarget: self action: @selector(gestureRecognizedStateObserver:)];

    if(self.selectedItemView && self.selectedItemView.isHighlighted) {
        [self.delegate contextSheet: self didSelectItem: self.selectedItemView.item];
    }

    [self closeItemsToCenterView];
}

@end

控制器源码:

//
//  VLDExampleViewController.h
//  VLDContextSheetExample
//
//  Created by Vladimir Angelov on 11/2/14.
//  Copyright (c) 2014 Vladimir Angelov. All rights reserved.
//

#import <Foundation/Foundation.h>
#import "VLDContextSheet.h"

@interface VLDExampleViewController : UIViewController <VLDContextSheetDelegate>

@property (strong, nonatomic) VLDContextSheet *contextSheet;

@end
//
//  VLDExampleViewController.m
//  VLDContextSheetExample
//
//  Created by Vladimir Angelov on 11/2/14.
//  Copyright (c) 2014 Vladimir Angelov. All rights reserved.
//

#import "VLDExampleViewController.h"
#import "VLDContextSheetItem.h"

@implementation VLDExampleViewController

- (void) viewDidLoad {
    [super viewDidLoad];
    [self createContextSheet];

    self.view.backgroundColor = [UIColor blackColor];

    UIGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget: self
                                                                                    action: @selector(longPressed:)];
    [self.view addGestureRecognizer: gestureRecognizer];
}

- (void) createContextSheet {
    VLDContextSheetItem *item1 = [[VLDContextSheetItem alloc] initWithTitle: @"Gift"
                                                                image: [UIImage imageNamed: @"gift"]
                                                     highlightedImage: [UIImage imageNamed: @"gift_highlighted"]];

    VLDContextSheetItem *item2 = [[VLDContextSheetItem alloc] initWithTitle: @"Add to"
                                                                image: [UIImage imageNamed: @"add"]
                                                     highlightedImage: [UIImage imageNamed: @"add_highlighted"]];

    VLDContextSheetItem *item3 = [[VLDContextSheetItem alloc] initWithTitle: @"Share"
                                                                image: [UIImage imageNamed: @"share"]
                                                     highlightedImage: [UIImage imageNamed: @"share_highlighted"]];

    self.contextSheet = [[VLDContextSheet alloc] initWithItems: @[ item1, item2, item3 ]];
    self.contextSheet.delegate = self;
}

- (void) contextSheet: (VLDContextSheet *) contextSheet didSelectItem: (VLDContextSheetItem *) item {
    NSLog(@"Selected item: %@", item.title);
}

- (void) longPressed: (UIGestureRecognizer *) gestureRecognizer {
    if(gestureRecognizer.state == UIGestureRecognizerStateBegan) {

        [self.contextSheet startWithGestureRecognizer: gestureRecognizer
                                               inView: self.view];
    }
}

- (void) willRotateToInterfaceOrientation: (UIInterfaceOrientation) toInterfaceOrientation
                                 duration: (NSTimeInterval) duration {

    [super willRotateToInterfaceOrientation: toInterfaceOrientation duration: duration];

    [self.contextSheet end];
}

@end
时间: 2024-12-29 11:39:03

[翻译] VLDContextSheet的相关文章

在GlassFish应用服务器上创建并运行你的第一个Restful Web Service【翻译】

前言 本人一直开发Android应用,目前Android就业形势恶劣,甚至会一路下滑,因此决定学习服务器开发.采用的语言是java,IDE是Intellij,在下载Intellij的同时看到官网很多优秀的guide文章,于是按照guide成功完成了一个RESTful的demo.官方文档非常简洁,给我带来了很大的帮助,于是翻译之,希望对其他不愿意看原文的人有所帮助.由于水平有限,读者发现错误请指正,谢谢. 原文地址: https://www.jetbrains.com/help/idea/2016

Java 7 Concurrency Cookbook 翻译 序言

在日常的Java代码开发过程中,很难免地有对多线程的需求,掌握java多线程和并发的机制也是Java程序员写出更健壮和高效代码的基础.笔者找寻国内已出版的关于Java多线程和并发的的中文书籍和翻译书籍,大家一致推荐的是<Java Concurrency in Practice>,笔者暂时还没有看英文原版,笔者看的是它的翻译版<Java并发编程实战>,笔者读起来感觉并不通畅,不知道是翻译的问题还是原版本来就写得不够流畅,同时感觉知识的深度也超过了入门的需求. 笔者在机缘巧合之下,发现

[翻译] ORMLite document -- How to Use Part (二)

前言 此文档翻译于第一次学习 ORMLite 框架,如果发现当中有什么不对的地方,请指正.若翻译与原文档出现任何的不相符,请以原文档为准.原则上建议学习原英文文档. ---------------------------------------------------------------------------------------------- 二.如何使用 2.7 表的创建 ORMLite 提供了一些工具类为您存储在数据库中的类创建 table 和 schema. 2.7.1 Tabl

Reveal常用技巧(翻译来自Reveal官网blog)

翻译来自官网:http://revealapp.com/blog/reveal-common-tips-cn.html 以下基于Reveal 1.6. 用于快速上手的内置应用 刚刚下载Reveal,啥都还没配置呢,想先随便玩玩看,怎么办? 我们花了不少时间开发这个复杂程度类似与实际场景的Sample应用──Soundstagram(音频分享版的Instagram, ¯\_(ツ)_/¯),就是为了让大家能最快速地上手Reveal,尝试它的各种强大功能. 在 Help 菜单项中,点击 Inspect

qt 国际化(翻译时会触发changeEvent)

1. 修改工程文件 .pro ,加入翻译源文件 hello_world.ts: TRANSLATIONS += \        Resource/translations/hello_world.ts 写代码时需要注意下面两点:  2. 源码用 utf-8 字符集3. 源码中需要翻译的字符串必须用英文(不能有中文或其它语言),则需要用 tr()  函数.  例如: QMessageBox::information(this,tr("Information"),tr("Hel

还在吐槽翻译的外版书质量差吗?谈谈我个人的理解

很难想象哪个学习计算机技术的人是没看过这方面书籍的,如果只是在网上看看技术贴,那样得来的知识绝对是离散的,不系统的.而要真正学好一门学问(比如一门计算机语言或者一门技术),一本好书的作用是不言而喻的.很多人抱怨国人在技术图书方面抄来抄去,不求甚解,虽然出版图书者甚众,但最终成为精品者却凤毛麟角.于是,更多读者热衷于外版书.但显然,并非所有国人的外语水平都足以在阅读原版书籍时毫无障碍.那么退而求其次,寻求翻译版就成为一种看似不得已的选择. 不幸的是,网上对于翻译版书籍的吐槽可以说从未消停.我也看过

VLD 1.0 ReadMe翻译尝试

近期想学习下VLD的实现,打算从最简单的V1.0版本看起.以下是V1.0版本自己尝试翻译下,最新的2.x版本似乎强大了很多. 简介 Visual C++提供了内置的内存检测机制,但其充其量只满足了最小定位需求.VLD工具定位为内置内存泄漏的替代,提供了如下特性: 泄漏内存块的全调用栈回溯,包括文件及其行号: 泄漏内存完整转储(hex和ascii格式): 可定制的泄漏报告等级(报告的详细程度可配置) 相对于Purify和BoundsChecher工具其是免费的,而其他免费工具,往往需要入侵式代码.

如何调用有道翻译API(Java,HTTP)

申请Key 首先如图进入有道翻译,在下方点击"有道翻译API". 紧接着来调用数据接口,按提示完成下列输入框. 如下图所示,已经申请成功了. 下图是官方给的示例,可以有xml和json.jsonp等三种数据格式. 代码(Java) public class TestPost { public static void main(String[] args) { new ReadByPost().start(); } } class ReadByPost extends Thread{ @

Android studio project文件结构翻译

Android studio project文件结构翻译 个人翻译,用作备忘. 链接地址:https://developer.android.com/tools/projects/index.html#ApplicationModules Android Project Files Studio的项目文件和设置,设置的作用范围包含所有的module. 以以下的demo为例. .git:git版本控制的文件存放目录. .gradle:gradle执行一些编译所生成的目录 Idea: 由Intell