Ok, so I will apologize in advance, but I am a complete noob to Swift and iOS development, but I really want to learn to code. I have followed quite a few tutorials and so forth online, but cannot seem to find an answer for this problem I am having. There has to be a simple solution to this because it doesn't seem like a very hard issue but the googles are not being my friend in finding an answer. I do not want to use storyboards because I want to learn the real meat and potatoes. I am using OS X 10.11, Xcode 7, writing the app for iOS 9, universal.
So, I designed a calendar app with quite a unique display, UI, and functionality than the other grid based calendars out there. I have a UIView that I want to be a container to hold the other views I need and pull them into the container view. The files I have are the included ViewController.swift and my custom files ContainerView.swift HeaderView.swift, CalView.swift, and CalDetailView.swift. I set classes for each file, the HeaderView is a basic UIView, CalView is a horizontal UIScrollView that enables pagination for the different calendar views like week, month, day, year, and so on. The CalDetailView is also a horizontal UIScrollView that will display event details to the user and also be the primary action area for the user for editing, adding events, etc.
Currently the ContainerView loads just fine and I can do whatever I want there and can create these other subviews without a problem but only in the ContainerView file. I want to keep these areas separated out into different files for my sanity and add them into ContainerView UIView as subViews with AutoLayout and everything, just like I am able to do inside the ContainerView file, but it would be enormous and I don't want that.
I believe the proper way to do this is to add these subViews under the viewDidLoad() method of the main VC and create my AutoLayout constraints in the VC file, then I just want to load my subViews in the ContainerView file and build the screen. The separate subView files will contain all of my drawing code and touch events and so forth for the views.
Here's a simple wireframe of what I am trying to accomplish...
The whole window is ContainerView.swift the rest, subViews of ContainerView.
WireFrame
This question is a little open ended and non specific, but let's ignore this for now (it is your first time), in future please be more specific, this is the kind of response a tutorial might be better providing. You will have enough to do, without avoiding Storyboards - feel free to use them.
In any case it is fine.
Given a UIView subclass MyView, in your main view controller:
override func viewDidLoad() {
super.viewDidLoad()
....
let myView = MyView()
self.view.addSubView(myView)
myView.frame = ... OR <SET CONSTRAINTS>
....
}
Essentially you will initialise those view subclasses and add them as appropriate.
Related
I am implementing a horizontal carousel-style character selection screen for a game (as per image below).
Image of carousel effect
The app is structured as one main GameViewController presenting different scenes; the CharacterSelectionScene being one of them.
From my research it seems that, although not always advisable to mix UIKit and SpriteKit elements, the best way to achieve the effect is the use a UIColectionView and add it as a subview to the scene. Because it takes care of the some of the animation and bounce effects.
Horizontal scrolling in SpriteKit (vs. a viewcontroller)
However, it's giving me a real headache! Using the post above as an example, I subclassed UICollectionView but I am unable to use the CharacterSelectionScene as the datasource and delegate! This would be ideal as the scene is where the data is loaded in from a plist.
I am currently using my CharacterCollectionView as the datasource and delegate by passing data from the scene via the collection view's init() a la:
collectionView = CharacterCollectionView(frame: customFrame, collectionViewLayout: layout, characterData: characterData)
This works but feels like a bad idea, it feels like a bit of a bodge. Maybe I'm wrong but as a fairly new programmer I'd just like to do this the right way!
Can anyone point me in the right direction? Am I going down completely the wrong path here or is this a perfectly good way to move forward. All advise/pointers appreciated!
Does anyone know of a comprehensive tutorial on implementation of PaintCode, using variables with it, and getting the view to update. I am struggling my way through it. I have built a custom class, and linked a view controller, with a UIView, and I can see the simple graph I made. I have linked it up so that it is #IBDesignable & #IBInspectable and both work fine. I am just not sure how to pass a variable through to the UIView.
I also have absolutely no idea how to get the thing to update when the variable changes.
Any assistance in this would be great, it has taken all day so far and I feel nowhere closer to solving the issue.
I do appreciate your time and effort.
There a many tutorials in PaintCode home page and at this other website, good lucky
However to access the values you create you just need to create an outlet from the UIView to your UIViewController class and class myViewName.myVariableName = myValue
As this step by step tutorial explain
The only tutorials I've found are the PaintCode website.
There are three things that I tend to adjust when trying to add/remove parameters to make my drawings more customizable via code.
When you click on a canvas, there is a drop down menu in the inspector that allows you to include a draw method, an image method, or both when you export the style kit.
When selecting the color in the color palette, there is a drop down menu in the upper right that allows you to make the color a parameter, so that when you export, you can set the color via code.
Add a frame to the canvas and set the constraints in the inspector. These constraints are the old style layout constraints that are very annoying, but doing this inserts a rect parameter in the exported methods which you can set in the code as well.
I don't know any other good PaintCode tutorials - over and above - the tutorials suggested. But after some research, I think I know the answer to your problem:
Background before the answer: I had the same problem. For example, you have a good sized image (created by PaintCode) that works on all iPhone device except the iPhone 4S.
To solve my issue:
Open PaintCode & find the “Frame” button.
Learn a new word “Parametric”. That is what we are dealing with. When the frame changes in size, you set whether the objects inside the frame change size or stay the same.
Watch the Dynamic Shapes tutorial on the PaintCode site. All of the answers are within this short youTube video. It took 5 times of watching it until I have extracted all of the information I needed to get it to work.
If you want the more details, keep reading:
#IBDesignable
class beerViewClass: UIView {
override func drawRect(rect: CGRect) {
SecurityStyleKit.drawCarDashboard(frame: self.bounds, wageIncome: "yo!")
}
}
Notice I can set the frame size as I have multiple views of the same image. Also I can send in variables to the drawCarDashboard.
Within PaintCode, put the objects you want to scale / shrink inside the frame.
Set the Springs and Struts for each item in the frame. For example, do you want it to shrink, stay vertically centered, etc.
Export your StyleKit to Xcode.
in Xcode, using Storyboard or code, add the UIViews to your View
Controller
Add a new Swift file.
Change the blank Swift file to a subclass of UIView & add code (see example)
In storyboard view, select the views that were added.
Set the view to the class you wrote (beerView)
I hope that helps. I hope my explanation was clear.
I am currently developing an iOS app and I was wondering how to manage the UI elements. I am using a Storyboard to place my views and Autolayout to make everything resolution independent. If it helps, here's a bit of background on how I came up with this question.
Some Backgroud
I have buttons the represent piano keys and I later in code add a subview to these that draws the actual keys on them. I did this by creating #IBOutlets on the ViewController and susbscribed to the UIDeviceOrientationDidChangeNotification. This called a method that adds the subviews based on the current button frames to get the appropriate sized keys.
This worked fine when running in iOS 8.1, but if I ran the app on iOS 7, the frames of the buttons weren't updated to the new orientation by the time I got the UIDeviceOrientationDidChangeNotification, so everything was messed up in landscape. I did a little research (UIInterfaceOrientation not yet updated when UIDeviceOrientationDidChangeNotification caught in UIView) and it seems that a good solution would be to override the layoutSubviews method. Problem is, layoutSubviewsis a UIView method, and I am managing my buttons and UI in my UIViewController.
Impulsively I wanted to subclass my UIView, override layoutSubviews and from there call a method on my Controller to add the keys to the buttons correctly, but that doesn't sound right.
The Questions
My UI is managed by the UIViewController. But I need to update my views based on a method proper of a UIView. I assume, to respect the MVC principles, that my view should't now a thing about my controller, but then this brings up a few questions:
Who should be managing the UI?
Is my strategy wrong and should the
UIView hold the #IBOutlets to the buttons so that it can later
apply the subviews I need them to have?
If you read the background, do you have a suggestion for this particular situation?
I assume the complexity of this problem is relatively small and I don't need to setup notifications in NSNotificationCenter, but I may be wrong. I would really like to hear this is not the only solution.
Thanks in advance. I hope I was clear enough, but if you want/need any additional details on my particular situation, let me know and I will gladly elaborate.
if I understood the question correctly, your ViewController should be laying out the keys within it's view. A good, but not the only, place to do this is in viewDidLayoutSubviews which a method you can override on UIViewController.
Now if your views should maintain their internal layout. i.e if you buttons/keys have any subviews, you should update those in layoutSubviews on UIView as you mentioned.
Both methods will be called in response to changes in the bounds or center of your parent view.
As far as rotation changes are concerned, in iOS 8, you should use viewWillTransitionToSize:withTransitionCoordinator: or willTransitionToTraitCollection:withTransitionCoordinator:
depending on your needs.
I highly recommend that you write your layout independent of orientation. You should just use the containing view's bounds for reference and never hard code in any frames. For example perhaps one of your keys should be 1/56 the width of it's superview instead of a magical number for portrait and landscape.
I've been banging my head with this issue for the last two days. Googled a lot but wasn't able to find the answer yet, so I decided to request some help here. Let's see if I get any luck.
I'm coding a reusable control that consists of an UIView with a variable number of customized UIButtons. I implemented initWithFrame:, initWithCoder: and drawRect: where the buttons (which are built prior to drawing) are actually added to the view. Everything is done programmatically since the UIButton content should be supplied when using the control, so there's no XIB for this UIView.
This UIView, let's call it CustomizableBarButton is then used in an UIViewController, let's call it MyTestViewController with a view on it, let's call it customizableBarButtonView.
MyTestViewController's GUI was set on IB where an UIView was tied to customizableBarButtonView (the class was matching accordingly).
MyTestViewController's is a pretty standard class except for the viewWillAppear: that initializes the buttons and passes them to the CustomizableBarButton along with some other options.
The issue is that everything works perfectly...except for the first time!
I mean, when I run the app on the simulator (I haven't tried it on the iPhone yet but I strongly believe that it's not an hardware issue) the MyTestViewController shows the customizableBarButtonView background but not the buttons. Now when you click on the place where a button should be all the buttons suddenly appear!
I'm puzzled since the CustomizablebarButton drawRect: runs before the strange "click n'appear" effect and the buttons are actually added to the subview.
Another hint that my help: if you don't click on the buttons (so you still got no buttons yet) but rotate the device they will also appear as if by magic!
It is probably something very simple but I'm missing it and I'm going nuts...
Can someone lend a hand on this, please?
Thanks in advance!
You said you're adding the buttons in drawRect:. Don't do that. You need to add the buttons in your init methods.
I think im missing something fundamental here because everyone seems to be able to do this simple task. Im trying to create an app that is very similar in presentation to the iPhone home screen (paging). I plan to have several pages that each have their own unique content. My understanding is that I can use UIScrollview to display and animate these pages/xib's but I have tried what seems like everything and am frustrated by the lack of instructions for newbs like me.
What I understand so far:
Declare IBOutlet UIScrollView *scroller
Set options in .m or in scrollview object via IB
connect fileowner of main .xib to *scroller
connect fileowner of main .xib to delegate
then somehow call in the other xib to load as the pages for the scrollview.
One thing i have found is that most of the tutorials and source codes i get are outdated or look different. Im using xcode 4.2. ANY HELP is greatly appreciated. Thanks!
I'm also a newbie so may be I don't understand your problem exactly but if you want to represent your scroll view in pages you should enable paging for it:
yourCoolScrollView.pagingEnabled = YES;