Coder Social home page Coder Social logo

tzstackview's Introduction

TZStackView Carthage compatible Swift 3.0.x

A wonderful layout component called the UIStackView was introduced with iOS 9. With this component it is really easy to layout components in a row both horizontally and vertically. Apple recommends using the UIStackView wherever possible and resort to explicit NSLayoutConstraints only when there is no way to do it with UIStackView. This saves you lots of boiler plate NSLayoutConstraint creation code.

UIStackView requires iOS 9, but we're not ready to make our apps require iOS 9+ just yet. In the meanwhile, we developers are eager to try this component in our apps right now! This is why I created this replica of the UIStackView, called the TZStackView (TZ = Tom van Zummeren, my initials). I created this component very carefully, tested every single corner case and matched the results against the real UIStackView with automated XCTestCases.

Features

  • ✅ Compatible with iOS 7.x and iOS 8.x
  • ✅ Supports the complete API of UIStackView including all distribution and alignment options
  • ✅ Supports animating the hidden property of the arranged subviews
  • ❌ Supports Storyboard

So this implementation does not support Storyboard. It is meant for iOS developers who, like me, want to use the UIStackView in our existing apps and like to layout their components in code as opposed to using Storyboard.

Setup

You basically have two options to include the TZStackView in your Xcode project:

Example Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, "8.0"
use_frameworks!

pod "TZStackView", "1.2.0"

Unfortunately, using CocoaPods with a Swift pod requires iOS 8.

Example Cartfile:

github "tomvanzummeren/TZStackView" ~> 1.2.0

Run carthage to build the framework and drag the built TZStackView.framework into your Xcode project.

Drag files directly into your project

Alternatively (when you do want to support iOS 7) drag in the following classes from the Example folder directly into your Xcode project

  • TZStackView
  • TZSpacerView
  • TZStackViewAlignment
  • TZStackViewDistribution

Example usage

Given view1, view2 and view3 who have intrinsic content sizes set to 100x100, 80x80 and 60x60 respectively.

let stackView = TZStackView(arrangedSubviews: [view1, view2, view3])
stackView.distribution = .FillEqually
stackView.alignment = .Center
stackView.axis = .Vertical
stackView.spacing = 25

This would produce the following layout:

TZStackView Layout example

See the developer documentation for UIStackView for all other combinatins of distributions, alignments and axis. TZStackView works and behaves exactly the same way as the UIStackView except for not supporting Storyboard. If you do find a case where it does not behave the same way, please file a bug report.

To animate adding a view to or removing a view from the arranged subviews, simply hide or show them by adjusting the hidden property within an animation block (as described by the UIStackView reference docs as well):

UIView.animateWithDuration(0.5, animations: {
	self.view2.hidden = true
})

TZStackView hidden animation example

Migrating to UIStackView

If at a later point you decide to make iOS 9 the minimum requirement of your app (it will happen sooner or later), you will want to migrate to the real UIStackView instead of using this implementation. Because the TZStackView is a drop-in replacement for UIStackView, you simply replace:

let stackView = TZStackView(arrangedSubviews: views)

with ...

let stackView = UIStackView(arrangedSubviews: views)

... and you're good to go! You will not need to make any other changes and everything will simply work the way it worked before.

License

TZStackView is released under the MIT license. See LICENSE for details.

tzstackview's People

Contributors

boek avatar igrandav avatar jernejstrasner avatar koreaparks avatar matthewcheok avatar readmecritic avatar regexident avatar rzulkoski avatar saramroo avatar tomvanzummeren avatar u10int avatar yoamfarges avatar zmian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

tzstackview's Issues

Unexpected behaviour with UILabel.numberOfLines = 0

I have a TZStackView hierarchy with a bunch of UILabels in it. They have numberOfLines = 0. The problem is that if I attempt the same code with UIStackView on iOS 9, or TZStackView on iOS 9, the UILabels wrap. However with TZStackView on iOS 8.x, the UILabel is ellipsized. Any thoughts on this?

NSInternalInconsistencyException when going back in navigation

Hello,

First, thanks a lot for your work !

I'm getting this error :

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'An instance 0x7c15b6a0 of class UILabel was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x7c170270> (
<NSKeyValueObservance 0x7c12bf90: Observer: 0x7c17a520, Key path: hidden, Options: <New: YES, Old: YES, Prior: NO> Context: 0x7c17a5b0, Property: 0x7c16fd30>

I'm using TZStackView inside a custom UIView for a simple test :

        let v1 = UILabel()
        v1.backgroundColor = UIColor.greenColor()
        v1.text = "efze"

        let v2 = UILabel()
        v2.backgroundColor = UIColor.blueColor()
        v2.text = "efze"

        let v3 = UILabel()
        v3.backgroundColor = UIColor.yellowColor()
        v3.text = "efze"

        container = TZStackView(arrangedSubviews: [
            v1,v2,v3
            ])

        container.setTranslatesAutoresizingMaskIntoConstraints(false)
        container.backgroundColor = UIColor.purpleColor()
        container.axis = .Vertical
        container.distribution = .FillEqually
        container.alignment = TZStackViewAlignment.Fill
        container.spacing = 15


        self.addSubview(container)

This UIView is displayed when the user selects an item in a collectionView (via a NavigationController) and the UIView with the TZStackView is correctly displayed.
The error happens when the user click the back button.

Did I do something wrong ? I saw a similar issue (#7) but I'm using 1.0.3 and it is still happening.

Thanks for your help !

README Confusion

Should the red X in the feature description be next to text stating "Supports Storyboard" or "Does not support storyboard". Putting the X next to "Does not support storyboard" seems like a double negative implying that it does support storyboard IMO. Just a nitpicky thought.

Compiler errors with Xcode 6.4 and Swift 1.2

Hi, I'm seeing compiler 14 errors for TZStackView for Xcode 6.4 and Swift 1.2 when using the following from CocoaPods:

pod 'TZStackView',              '~> 1.1.2'

or

git: 'https://github.com/tomvanzummeren/TZStackView.git'

TZStackView not animating “outside” views as UIStackView

Hi!
I’ve been replacing UIStackView with TZStackView and I’ve found that it handles animations (when arranged subviews are hidden) in a different way.

You can check the example on my fork.

The basic idea is having the stack view size itself depending on the content and then have another view attached at the bottom of it (as a sibling in the hierarchy). Then when hiding any arranged subview with animation the stack view should resize itself and the outside view move accordingly.

The issue is that when that happens with TZStackView, the stack view is animated but the outside view isn’t. Check this .gif for a quick look.

UIStackView

animationui

TZStackView

animationtz

Cheers.

how to add tzstackview on scrollview.

Hi,
i want to use tzstackview on scrollview to add dynamic content .when i try to add multiple contents on
tzstackview it gives them equal heights. i'm adding tzstackview on scrollview

var tzStackView: TZStackView!

override func viewDidLoad() {
super.viewDidLoad()
tzStackView = TZStackView(arrangedSubviews: createViews())
// tzStackView.backgroundColor = UIColor.redColor()
tzStackView.translatesAutoresizingMaskIntoConstraints = false
tzStackView.axis = .Vertical
tzStackView.distribution = .Fill
tzStackView.alignment = .Fill
tzStackView.spacing = 15

  self.scrollView.contentSize = CGSizeMake(self.view.bounds.size.width,      self.view.bounds.size.height * 2);

self.scrollView.addSubview(tzStackView)

let horizontalConstraint = NSLayoutConstraint(item: tzStackView, attribute: NSLayoutAttribute.Trailing, relatedBy: NSLayoutRelation.Equal, toItem: self.scrollView, attribute: NSLayoutAttribute.Trailing, multiplier: 1, constant: 0)

self.view.addConstraint(horizontalConstraint)

let verticalConstraint = NSLayoutConstraint(item: tzStackView, attribute: NSLayoutAttribute.Leading, relatedBy: NSLayoutRelation.Equal, toItem: self.scrollView, attribute: NSLayoutAttribute.Leading, multiplier: 1, constant: 0)
view.addConstraint(verticalConstraint)

let bottom = NSLayoutConstraint(item: tzStackView, attribute: NSLayoutAttribute.Bottom, relatedBy: NSLayoutRelation.Equal, toItem: self.scrollView, attribute: NSLayoutAttribute.Bottom, multiplier: 1, constant: 0)
view.addConstraint(bottom)

let top = NSLayoutConstraint(item: tzStackView, attribute: NSLayoutAttribute.Top
  , relatedBy: NSLayoutRelation.Equal, toItem: self.scrollView, attribute: NSLayoutAttribute.Top, multiplier: 1, constant: 0)
view.addConstraint(top)

}

private func createViews() -> [UIView] {

let textfield = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 100.00));
let textfield1 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield2 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 130.00));
let textfield3 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield4 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield5 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield6 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield7 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield8 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield9 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield10 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));
let textfield11 = UITextField(frame: CGRect(x: 0, y: 0, width: 500.00, height: 30.00));

textfield1.backgroundColor = UIColor.redColor().colorWithAlphaComponent(0.75)

return [textfield, textfield1, textfield2, textfield3, textfield4,textfield5,textfield6,textfield7,textfield8,textfield9,textfield10,textfield11]

}

i want tzstackview height same as scrollview.

IOS7 Support?

hi,
Your description says project is compatible with ios7+ but when i tried to use i get errors
**
TZStackView/TZStackView.swift:320:84: 'BottomMargin' is only available on iOS 8.0 or newer
TZStackView/TZStackView.swift:321:84: 'LeftMargin' is only available on iOS 8.0 or newer
TZStackView/TZStackView.swift:322:84: 'RightMargin' is only available on iOS 8.0 or newer
TZStackView/TZStackView.swift:323:84: 'TopMargin' is only available on iOS 8.0 or newer
TZStackView/TZStackView.swift:484:74: 'FirstBaseline' is only available on iOS 8.0 or newer

**
ps: i'm using ios7.1+

UIImageView contentMode not working

    let imageView1 = UIImageView(image: UIImage(named: "goods.png"))
    imageView1.contentMode = .ScaleToFill
    imageView1.clipsToBounds = true
    imageView1.sizeToFit()

    contentContainerView.addArrangedSubview(imageView1)

    let imageView2 = UIImageView(image: UIImage(named: "goods.png"))
    imageView2.contentMode = .ScaleToFill
    imageView2.clipsToBounds = true
    imageView2.sizeToFit()
    contentContainerView.addArrangedSubview(imageView2)

contentMode not working

Question: variable spacing

Hi, I would like to make a stack view where spacing is 0 for all but one view. I thought I could just add constraint and give it bigger priority but what I can see in the code, TZStackView constraints are created with priorities required (=1000) so I can not override them.

The layout: V:[UILabel]-(0)-[UILabel]-(10)-[UIImageView]

Is this possible or am I missing something?

This is code creating the stack view:

let stack = TZStackView(arrangedSubviews: [placeLabel, addressLabel, mapView])
stack.axis = .Vertical
stack.alignment = .Leading

Crash when using someviewinsidestack.hidden = true

I'm getting a crash when I'm trying to hide some of my views from the stack. I tried to remove two different views from my stack, one that doesn't have constraints inside, and another that does. The first one hides normally, the second one causes my application to crash. I'm using SnapKit to set contraints and I'm still using Swift 1.2.

I don't have time to provide more details now. Later today I'm going to try to reproduce this error in the demo app, then I'll post an update.

Thanks.

Inserting a view

I didn't really have time to check but from what I've seen, the method

public func insertArrangedSubview(view: UIView, atIndex stackIndex: Int) {
    view.translatesAutoresizingMaskIntoConstraints = false
    addSubview(view)
    arrangedSubviews.insert(view, atIndex: stackIndex)
}

shouldn't be

public func insertArrangedSubview(view: UIView, atIndex stackIndex: Int) {
    view.translatesAutoresizingMaskIntoConstraints = false
    insertSubview(view, atIndex: stackIndex)
    //      addSubview(view)
    arrangedSubviews.insert(view, atIndex: stackIndex)
}

?

Swift 2.3/3.0 support

Just curious if this is being worked on by anyone?
May be a pretty simple conversion after Xcode 8's covert tool.
(I may give it a shot but I really don't know Swift 😅 )

UIViewAlertForUnsatisfiableConstraints error while hiding a view

I have a UIView that contains few buttons. They are all separated from each other with 8 points space. The buttons have no height constraints.

This view is then added to your stackview and the axis is set to vertical.
When I hide the view, it actually set a constraint saying the view should have a height of 0.
Then I get an UIViewAlertForUnsatisfiableConstraints error because I have some fixed constraints (8 points gaps) in my view.

What's my solution to avoid those errors?

Thanks.

Interface Builder

I know your documentation says that this is not supported, but the use of Interface Builder and UIStackView are not mutually exclusive. There is no reason that I shouldn't be able to put a stack view in an Interface Builder document and use it to manage the auto layout constraints I would have had to write otherwise.

TZStackView tests do not pass in Beta 4 or Beta 5

Hey Tom,
It looks as thought the tests are no longer correct at least as of Beta 4.

In Beta 4:
It seems that the order of the constraints is not the same between UIStackView and TZStackView even though the constraints themselves appear to be the same. Is the order of the constraints important? If not I can fix the tests so that they do not rely on order.

In Beta 5:
It looks at though UIStackView has one more constraint than TZStackView which is triggering a failure in the count assertion as well as all the test failures above. Little less confident about my ability to track this one down.

Setting TZStackView to hidden inside animateAlongsideCoordinator's animation block causes strange behavior

I have discovered a bug when attempting to set a TZStackView's hidden property during rotation. Specifically, I am attempting this inside of viewWillTransitionToSize(size:coordinator)'s coordinator.animateAlongsideTransition(animate:completion:)'s animation block.

On the first rotation everything appears to work as expected. However, on all subsequent device rotations viewWillTransitionToSize is never called. I have tracked this issue down to this block of code inside of TZStackView.swift:

 116|  if let _ = view.layer.animationKeys() {
*117|      UIView.setAnimationDelegate(self)
 118|      animationDidStopQueueEntries.insert(TZAnimationDidStopQueueEntry(view: view, hidden: hidden), atIndex: 0)
*119|      UIView.setAnimationDidStopSelector("hiddenAnimationStopped")
 120|  } else {
 121|      didFinishSettingHiddenValue(view, hidden: hidden)
 122|  }

It would seem that Apple is internally setting and relying on being the animationDelegate and setting an instance of TZStackView to the animationDelegate interferes with this. When I comment out every line except line 121 it works fine for the most part EXCEPT when animating hidden = true. This causes the view being hidden to hide immediately while the views around it properly animate to fill the empty space. I haven't gotten to the point where I understand exactly how you are orchestrating the animations yet so I'm afraid I don't have a suggestion as to how to fix the issue. Do you have any other methods at your disposal to accomplish whatever it is you are doing rather than setting yourself as the animation delegate? I'm looking forward to hearing your thoughts and I will continue to investigate the issue in the meantime.

I have uploaded a project demonstrating the bug to GitHub.

Thanks for your time and efforts.
/cheers

Works only with Swift?

I guess this fantastic Project will only works with Swift? Because my whole project is written in Objective c and i don´t have the time to change everything to Swift in the near future.

How do I get the fitting size of either TZStackView or the UIStackView?

https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIStackView_Class_Reference/ has a section called Positioning and Sizing the Stack View — I don't understand this wording:

  • Along the stack view’s axis, its fitting size is equal to the sum of the sizes of all the arranged views plus the space between views.
  • Perpendicular to the stack view’s axis, its fitting size is equal to the size of the largest arranged view.
  • If the stack view’s layoutMarginsRelativeArrangement property is set to YES, the stack view’s fitting size is increased to include space for the margins.

This fitting size is exactly what I need — how do I get to it?

Cut a release for the frameworks pull request

The latest release doesn't have a framework target. Throwing Dependency "TZStackView" has no shared framework schemes when installing via Carthage.

The latest commit on master fixes it, but there isn't a release for it :)

Make TZStackView open to allow subclassing

TZStackView cannot be subclassed in Swift 3, since the class is public instead of open.

We have to add some additional functionality to this class, so it would be great if you could make this class open. Thanks!

Constraint Equality Test

In this function

private func hasSameConstraintMetaData(layoutConstraint1: NSLayoutConstraint, _ layoutConstraint2: NSLayoutConstraint) -> Bool {
    if layoutConstraint1.constant != layoutConstraint2.constant {
        return false
    }
    if layoutConstraint1.multiplier != layoutConstraint2.multiplier {
        return false
    }
    if layoutConstraint1.priority != layoutConstraint2.priority {
        if layoutConstraint1.priority < 100 || layoutConstraint1.priority > 150
            || layoutConstraint2.priority < 100 || layoutConstraint2.priority > 150 {
                return false
        }
    }
    return true
}

What is the purpose of the last if statement?

        if layoutConstraint1.priority < 100 || layoutConstraint1.priority > 150
            || layoutConstraint2.priority < 100 || layoutConstraint2.priority > 150 {
                return false
        }

I found if remove this and directly return false when the priorities are not equal the tests can still pass.

insertArragnedSubview:atIndex: has a partial implementation.

Based on the docs insertArragnedSubview:atIndex: should also add the view to its subviews.

https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIStackView_Class_Reference/#//apple_ref/occ/instm/UIStackView/insertArrangedSubview:atIndex:

the stack view appends the view to the end of its subviews array. The index only affects the order of views in the arrangedSubviews array. It does not affect the ordering of views in the subviews array.

boek@5cf0642 (I'll split it out into it's own pull request)

Swift 2.0 Status?

Hi,

I see there is a branch that is actively being worked on for Swift 2.0 support. I was wondering what the status of this branch is and if any help was needed to progress it.

Cody

Issues with right to left languages for iOS 7 and 8

So the issue is that UIStackView was not introduced until iOS 9 and iOS 9 flips all the native controls for right to left languages. So using .Leading and .Trailing is correct since it will respect the language direction. But for iOS 7 and 8 where the user interface direction is not swapped using .Leading and .Trailing is not really appropriate. It should probably be using .Left and .Right. Another small issue is that .Leading and .Trailing is not technically supported in iOS 7.

I am thinking maybe TZStackView needs a .Left and .Right alignment option. Or the class can just handle using the desired layout attribute by iOS version.

A way to safely remove a arranged subView

The current implementation of removing arrangedSubView is not great because even after removing arranged subView the view is still present. Remove arrangedSubView should work as expected.

A bonus would be if we can remove all the arrangedSubViews together. Some thing like -

@objc func removeAllArrangedSubViews() { for arrangedSubView in arrangedSubviews { removeArrangedSubview(arrangedSubView) arrangedSubView.removeFromSuperview() } updateConstraints() }

Storyboard support

Hey,

First of all, thanks for making this publicly available. I certainly prefer this one over OAStackView. I really don't understand why people are making a big deal about TZStackView being "redundant"... It's not redundant! It's awesome, currently is more complete (certainly appreciate the drop-in replacement) and it's all in pure swift!

The only thing that's missing is storyboard support, but I understand that you purposely designed it to be that way.

I was just wondering if it would be difficult or a huge task to add storyboard support? I will attempt it and even submit a PR if I manage to implement it/if you're open for PRs, but just thought I'd ask if it would require a significant amount of work? I've never really done that before so any tips would be appreciated. :)

Thanks

Crash on deinit `UIView was deallocated while key value observers were still registered with it`

I have a crash:

Fatal Exception: NSInternalInconsistencyException
An instance 0x151eabd0 of class UIView was deallocated while key value observers were still registered with it. Current observation info: <NSKeyValueObservationInfo 0x151b6c10> ( <NSKeyValueObservance 0x14384cd0: Observer: 0x151b0090, Key path: hidden, Options: <New: YES, Old: YES, Prior: NO> Context: 0x151b0180, Property: 0x8814fc0> )

In my view I have this code:

deinit {
    stackView.arrangedSubviews.forEach { view in
      stackView.removeArrangedSubview(view)
    }
  }

After investigation I found that method removeArrangedSubview does not call removeHiddenListener. Why?

You are removing listeners by code:

deinit {
        // This removes `hidden` value KVO observers using didSet()
        { self.arrangedSubviews = [] }()
    }

But arrangedSubviews are already empty. Why don't you remove listeners for all listeners in registeredKvoSubviews array?

Trouble importing into ObjectiveC project

This probably isn't a TZStackView issue, but my own ignorance on this one. I have an objective c project and am trying to import TZStackVew. I've read up on the Autogenerated header but it's never generated for me. Here's what I've done

Dragged the following to my project
TZSpacerView.swift
TZStackView.h
TZStackView.swift
TZStackViewAlignment.swift
TZStackViewDistribution.swift

My understanding is a header is auto generated allowing me to access these. I am able to compile with these in my project as long as I don't use them in any way. I'm not seeing any auto generated header.

After searching around the internet for help I go to build settings and under packaging look at "Product Module Name" and "Product Name", they are actually blank if I'm looking at the global project. If I click on my targets (I have 2, one for a free ver of my app and one for a paid) I see "Upwords" and "Upwords_Free" for the free one.

I've tried

import "Upwords-Swift.h"

or

import "Upwords_Free-Swift.h"

I also tried typing in an arbitrary name at the project level (not the targets) and no luck there either.

The headers are never found. I know this isn't really your issue.. but if you have a quick answer I'd appreciate it. I noticed I can build a framework from your project. I did try building one and dragging that in but didn't help either. My first toe dip into swift

Thanks for any pointers
Daniel

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.