after my last question, regarding accessing an array from a different class, I ran into an new problem, that's giving me a headache for three days now. Everytime I think I have the correct solution approach, I fail.
Well... I don't have many experience yet regarding Cocoa Programming. But maybe you are able to give me the missing hint.
Let me show you what approach I've chosen:
1) the declaration of an array in the class PortConnection.h/.m
#interface PortConnection : NSObject {
#private
NSMutableArray *baudArray;
}
#property (nonatomic, retain) NSMutableArray *baudArray;
and the synthesize in .m
#implementation PortConnection
#synthesize baudArray;
Next I decided to implement a method in the ViewController that should be in charge of filling the array with data I need for display. The name of the class is "PortTableViewController.h"
#import "PortConnection.h"
#interface PortTableViewController : NSObject <NSTableViewDataSource, NSComboBoxDataSource> {
#private
IBOutlet NSComboBox *baudSelection;
PortConnection *portConnection;
}
#property (assign) IBOutlet NSTableView *portTableView;
- (IBAction)fillBaudSelection:(id)sender;
#end
and the implementation of my method "fillBaudSelection".
- (IBAction)fillBaudSelection:(id)sender {
int baudCount = [portConnection.baudArray count];
int i;
for (i = 0; i <= baudCount; i++){
[baudSelection addItemWithObjectValue:[portConnection.baudArray objectAtIndex:i]];
}
}
Furthermore I implemented the delegate methods for the combobox.
- (id)comboBox:(NSComboBox *)aComboBox objectValueForItemAtIndex:(NSInteger)index{
return [portConnection.baudArray objectAtIndex:index];
}
- (NSInteger)numberOfItemsInComboBox:(NSComboBox *)aComboBox{
return [portConnection.baudArray count];
}
My questions are:
1) Do I need to use the Delegate Methods for a combo box at all?
2) the Combobox isn't filled with data at all, though the array is filled with data
3) Am I thinking to complicated??
Thanks so much for every hint I get from you!
best Regards
Sebastian
Are you sure you hooked the combobox correctly? make sure the delegate and the datasource are set to whatever class has the methods implemented.
Related
I am struggeling with swift syntax . I want to add objects to an array but I have syntax errors.
The array is located in class Document, and the class that should add objects is in class Viewcontroller.
The array is of type Content:
public class Content: NSObject {
#objc var bankAccSender: String?
#objc var bankAccReceiver: String?
Declaration snippest in Document:
class Document: NSDocument {
var content=[Content]()
override init() {
super.init()
self.content = [Content]()
// force one data record to insert into content
content += [Content (… )] // checked with debugger
The ViewController has assigned the represented Object
contentVC.representedObject = content
But adding data in ViewController gives a compiler error „Type of expression is ambiguous without more context“:
var posting = Content(…)
self.representedObject.append(posting)
Hope you can help..
You can't append an element to an object of type Any. What you need is to replace the existing value with a new collection:
representedObject = (representedObject as? [Content] ?? []) + CollectionOfOne(posting)
representedObject is of type Any?, which is a very difficult type to work with in Swift. Since you already have a content property, I would probably adjust that, and then re-assign it to representedObject.
You can also try this (untested), as long as you are certain that the type is always [Content]:
(self.representedObject as! [Content]).append(posting)
It's possible you'll need some more complex like this:
(self.representedObject as! [Content]?)!.append(posting)
As I said, Any? is an incredibly obnoxious type. You probably want to wrap this up into a function. Or I you can avoid using representedObject, then I would recommend that. In many cases you don't need it. It's often just a convenience (in ObjC; in Swift, it's very hard to use).
Is there a way to document that a certain class has magic methods for every method defined in another class?
I am using PhpStorm, so I would be happy with any solution that will get autocomplete to work properly for that.
class A
{
// a bunch of functions go here...
}
/**
* Class B
* What should go here to make it work???
*/
class B
{
private $aInstance;
public function __construct() {
$this->aInstance = new A();
}
public function __call($name, $arguments) {
// TODO: Implement __call() method.
if(method_exists($this->aInstance, $name)) {
return $this->aInstance->{$name}(...$arguments);
}
throw new BadMethodCallException();
}
// a bunch more functions go here...
}
The proper solution is to use supported #method PHPDoc tags. This way it will also work in other editors/IDEs that support PHPDoc and understand such standard tag.
This approach requires every method to be listed separately. More on this in another StackOverflow question/answer: https://stackoverflow.com/a/15634488/783119.
In current PhpStorm versions you may use not-in-PHPDoc-specs (and therefore possibly PhpStorm-specific) #mixin tag.
Adding #mixing className in PHPDoc comment for your target class should do the job for you.
/**
* Class B
*
* #mixin A
*/
class B
{
Basically, #mixin tag does what actual PHP's traits do.
Please note that there is no guarantee that support for such tag will not be removed at some point in the future, although it's pretty unlikely.
I'm new to iOS programming, I read a lot of tutorials and forums but I still can't figure the best way to manage a project.
What I want is the iPad screen to display a CollectionView and a TableView side by side.
Actions in the CollectionView should change TableView content. SplitViewController won't do the job because of the fixed size of the split.
For now I'm using Storyboard, I created a ViewController and added two ContainerViews in it. Each container is linked by an XCode generated segue to a view controller (LeftViewController and RightViewController).
I'm trying to figure the smartest way to manage actions on the LeftViewController and send changes to the RightViewController.
I would like to use Storyboard that seems more elegant, but I'm not sure how to implement this.
Assuming you know the way to establish delegate methods (#protocol, see here for links), the key elements will be grabbing the two viewControllers embedded in containers as they are being loaded, setting the primary viewController as delegate, and sending the messages when something changes. For starters, if communication needs to flow both ways between controllers, set up an instance variable for each VC.
Given VCPrime, CollectionVC, and TableVC:
First, in storyboards, name each of your segues (from the containerViews to the VCs). In VCPrime, implement prepareForSegue:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"collection"]) {
self.collectionVC = (CollectionVC *)[segue destinationViewController];
self.collectionVC.delegate = self;
}
if ([segue.identifier isEqualToString:#"table"]) {
self.tableVC = (TableVC *)[segue destinationViewController];
self.tableVC.delegate = self;
}
}
You must also implement the delegate methods in VCPrime, and declare CollectionDelegate, TableDelegate, or however you named them.
In CollectionVC, when someone selects something (or whatever), check that the delegate responds to your delegate method, then send that message:
if ([self.delegate respondsToSelector:#selector(doSomething)]) [self.delegate doSomething];
Then alter TableVC in the method that is called.
This is just a quick rundown. The internets are alive with great code examples.
I think I might have an improvement in Swift (the answer is old but I was facing this problem a day ago). I re-implemented the above in Swift, but with a twist. Instead of setting the VCPrime as a delegate for for both CollectionVC and TableVC, I would make the TableVC a delegate of CollectionVC. That is because CollectionVC needs to control TableVC. In general we can call a "master VC" the one that controls and the "delegate VC" the one that is controlled. In order to make sure that both VC are actually instantiated when I set one as the delegate of the other, I use Swift optionals and optional bindings. Here is a sample of code" (note that the master needs to have a "delegate" property and you might want to declare the appropriate protocols):
import UIKit
class ContainerController: UIViewController {
private var masterViewController: myMasterViewController?
private var delegateViewController: myDelegateViewController?
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "myMasterViewController" {
masterViewController = segue.destinationViewController as? myMasterViewController
} else if segue.identifier == "myDelegateViewController" {
delegateViewController = segue.destinationViewController as? myDelegateViewController
}
if let master = masterViewController, delegate = delegateViewController {
println("Master and delegate set")
master.delegate = delegate
}
}
}
I have written code such as the following, which by assumption shouldn't compile. I'm assuming that it shouldn't compile because the instance methods are not declared in the interface. Is this necessary, either way what's the logic behind it?
Thanks :-)
#interface Foo: NSObject
{
}
#end
#implementation Foo
-(void) blank
{
NSLog(#"Hey this works");
}
-(void) foo
{
NSLog(#"Strange");
}
#end
What is the question here? This code compiles just fine as methods do not need to be declared in the interface.
I created an array of ImageViews in a Buttonclicked method:
UIImageView *arrayOfImageViews[10]
I successfully loaded them on the screen using a loop. (Big accomplishment for this beginner!)
But I want to refer to them in other methods (e.g. touchMove).
Where do I declare arrayOfImageViews to be both an array and a class of UIImageView so that I can use them in other methods? From what I can find, I'm to declare them in the .h and above Implementation in the .m. But I can't figure out the code and location to define the object as an array of UIImageViews in anything but the original function.
Try using a property. So in the .h file, you want to define the property something like this:
#interface MyClass: UIView {
NSArray *arrayOfImageViews;
}
#property (nonatomic,retain) NSArray *arrayOfImageViews;
Now in the implementation (.m file) You need to bind this property like this
#implementation MyClass
#synthesize arrayOfImageViews;
//now you need to initialize the array of images like this (look for the method viewDidLoad or //just add it)
- (void)viewDidLoad
{
NSMutableArray *tmpImages = [[NSMutableArray alloc]init];
//initialize images here
[self setArrayOfImageViews:tmpImages];
[tmpImages release];
[super viewDidLoad];
}
That should do it... Sorry I didn't have time to post code that actually compiles but it should help. Basically now you have a property on the class and you can access it like self.arrayOfImages, or even just arrayOfImages (from within MyClass). Also, I used NSArray which I suggest you do too. However you can also use UIImageView* arrayOfImages if you prefer.