Problem with UICustomSwitch, - ios4

I am using UICsutomSwitch for my application. When I try to create it, I am getting an exception like,
Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSArray objectAtIndex:]: index 2 beyond bounds for empty array'
My code is as follows,
UICustomSwitch.h
#import <Foundation/Foundation.h>
#interface UICustomSwitch : UISwitch
{
}
-(void)setLeftLabelText:(NSString *)labelText;
-(void)setRightLabelText:(NSString *)labelText;
#end
UICustomSwich.m
#import "UICustomSwitch.h"
#implementation UICustomSwitch
-(UIView *)slider
{
return [[self subviews ] lastObject];
}
-(UIView *)textHolder
{
return [[[self slider] subviews]objectAtIndex:2];
}
-(UILabel *)leftLabel
{
return [[[self textHolder] subviews]objectAtIndex:0];
}
-(UILabel *)rightLabel
{
return [[[self textHolder] subviews]objectAtIndex:1];
}
-(void)setLeftLabelText:(NSString *)labelText;
{
[[self leftLabel] setText:labelText];
}
-(void)setRightLabelText:(NSString *)labelText
{
[[self rightLabel]setText:labelText];
}
#end
View Controller:
UICustomSwitch* switchView=[[[UICustomSwitch alloc]initWithFrame:CGRectMake(200,5,90,30)]autorelease];
[switchView setLeftLabelText:#"F"];
[switchView setRightLabelText:#"M"];
[switchView addTarget:self action:#selector(genderAction:) forControlEvents:UIControlEventValueChanged];
[elementView addSubview:switchView];
I am getting exception at " return [[[self slider] subviews]objectAtIndex:2];" call. I don't know what is the wrong, Can you guys please suggest me on this.
Thanks in advance,
Sekhar.

I ran across this issue and found the answer here:Custom UISwitch Text
Basically in iOS 4, there were UILabel's in the UISwitch's subviews that represented the "On/Off" labels. In iOS 5, there are no UILabels in the subviews array (hence the array error you're getting). The above link offers an external class you can download and customize. In my opinion, it seems like Apple is discouraging customization of UISwitch. The functionality you're after could be accomplished another way (segmented control, simulated checkbox, etc).
Also, in the given link above, the author proposes that the issue might be with not including armv6. I tried this and it does not fix the problem.

The exception indicates you are attempting to access an element of the array that is out of bounds (in a place that is larger than the actual size of the array).
You can use breakpoints and/or NSLog() calls carefully placed in your code to determine if this array ever is not-empty, and if that is so, you can continue to use these calls to find out just where the array becomes empty.
Clearly if the array is empty then the switch is setup differently than you expect it to be.

Related

KVO notification with Core Data in Swift

When I generate an NSManagedObject subclass with swift, the property types are all #NSManaged, meaning I can't observe them. This is a problem when using bindings in a Cocoa application because updating the property frequently requires other properties to be 'updated'.
For example, if I add this method to my NSManagedObject subclass:
dynamic var ratePerPoint: Double {
guard pointsPerMonth > 0 else { return 0 }
return monthlyRate / Double(pointsPerMonth)
}
Then it's important that whenever I update the pointsPerMonth variable, which is part of the core data object, that I send a didChangeValueForKey("ratePerPoint") message.
If I don't, then the UI bindings don't update properly.
If ratePerPoint is a calculated property you have to implement keyPathsForValuesAffectingRatePerPoint in your NSManagedObject subclass.
+ (NSSet *)keyPathsForValuesAffectingRatePerPoint {
return [NSSet setWithObjects:#"monthlyRate", #"pointsPerMonth", nil];
}
Documentation: Registering Dependent Keys

TypeInitializationException/ArgumentException when referencing initialized variable

I just received an exception when I try to reference a static variable in another class, which is also statically initialized. This worked before, and for some reason it fails now. The only changes I made were resetting Visual Studio (2010) to its default setting, which I can't imagine to be the reason for this. Any other code I added didn't touch any of the affected parts either.
This is my code
WinForms class 'MainForm':
partial class MainForm : Form
{
// ...
private RefClass convMan;
private Dictionary<EnumType, string> LogNames = RefClass.LogNames;
// ...
public MainForm() { .... }
}
Referenced class 'RefClass':
class RefClass
{
// ...
public enum EnumType { TypeOne = 0, TypeTwo = 1, TypeThree = 2 };
public static Dictionary<EnumType, string> LogNames = new Dictionary<EnumType, string>()
{
{ EnumType.TypeOne, "Text0" },
{ EnumType.TypeTwo, "Text1" },
{ EnumTypy.TypeThree, "Text2" }
};
}
The error I get now is (translated from German):
An unhandled exception of type "System.TypeInitializationException" occurred.
Additional information: The type initializer for "RefClass" threw an exception.
which has the InnerException
System.ArgumentException
So, as far as I'm concerned, my static dictionary should be initialized once it gets accessed, thus when my Form class references it. I tried debugging to see if the static dictionary is initialized before it gets referenced in the Form class, which is not the case. Also, when I stop at a breakpoint for the reference line, the variable LogNames is null.
I'm really confused as to why this happens, it all worked before.
I found my error, the exceptions I got were quite misleading though. It was a problem with a different dictionary than the one I referenced. It probably didn't get initialized in the first place because something before that failed (If someone can clear this up, please feel free to do so!). Basically what I did wrong was using a two-directional dictionary and adding a value twice. This should normally produce a normal exception, but since it was done statically it got wrapped into a TypeInitializationException. I had a deeper look into the exact stacktrace of the inner exception and found where the exception originated from. Maybe this helps someone in the future...
I had a simular issue getting the same exception. Found that my static constructor for my utility class was generating the exception. Took some time locating since the description of the exception was misleading.
As #Yeehaw mentioned, it appears that the exception gets wrapped, so the common denominator here I would say is that the class/object is static.

CustomDraw remains in PrePaint drawstage

I am facing some troubles when processing the NM_CUSTOMDRAW message on 64 bit machines. We have an CListCtrl derived class with a CHeaderCtrl derived header (linked via PreSubclassWindow).
In the CHeader derived class we do some custom painting. This works for a 32bit build. But when I build a 64bit variant the drawstage remains CDDS_PREPAINT.
So I am posting here to get some help on this issue. I tried a lot of combinations of result values, drawstage handling in the OnCustomDraw ... but all of them still receive only the CDDS_PREPAINT drawstage.
Here you have my current testcode for OnCustomDraw:
void CListViewCtrlExHeader::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)
{
LPNMCUSTOMDRAW lpnmcd = (LPNMCUSTOMDRAW )pNMHDR;
*pResult = CDRF_DODEFAULT;
if (lpnmcd)
{
switch (lpnmcd->dwDrawStage)
{
case CDDS_PREERASE:
{
TRACE(_T("CDDS_PREERASE\n"));
*pResult |= CDRF_NOTIFYPOSTERASE;
break;
}
case CDDS_POSTERASE:
{
TRACE(_T("CDDS_POSTERASE\n"));
break;
}
case CDDS_PREPAINT:
{
TRACE(_T("CDDS_PREPAINT\n"));
*pResult |= CDRF_NOTIFYPOSTPAINT;
break;
}
case CDDS_POSTPAINT:
{
TRACE(_T("CDDS_POSTPAINT\n"));
break;
}
default:
{
TRACE(_T("CDDS_OTHER\n"));
break;
}
}
}
}
The only purpose of this header ctrl is painting above the default painting, so there is not much code in there. The painting of the CListCtrl derived class does not not do anything special, it lets CListCtrl handle the OnPaint message. The CListCtrl derived class does contain an OnCustomDraw section. But since it works on 32 bit, I doubt the problems should be searched there, on the other hand I mention it since I am out of options...
I found some posts with similar issues (only64 bit or drawstage remains) but none of them worked for me. One of these solutions was an incorrect definition of NMCUSTOMDRAW struct, but mine is the MFC version and no complaints found for 64bit for it. Another was that result did not get processed because of where the component was placed, but then it should not work on 32 bit too. Other solutions are specific for handling the OnCustomDraw messages and results, but that seems to be fine for my testcode...
Kind Regards,
Kevin

Passing A Delegate In prepareForSegue Method

I am having a problem passing an object from a TableView to a ViewController in an IOS app. I am using storyboard and have elected ARC and passing the delegate in my "prepareForSegue" method.
Here is my code in my TableView which segues via a push to another ViewController:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
NextViewController *vc = (NextViewController *)[segue destinationViewController];
vc.managedObjectContext = managedObjectContext;
if ([[segue identifier] isEqualToString:#"EditCategory"])
{
NSInteger selectedIndex = [[self.tableView indexPathForSelectedRow] row];
// I get a red warning which states "Cast of 'NSInteger' (aka 'int') to 'Entity' is disallowed with ARC" on this line:
[vc setEntity:(Entity *)selectedIndex];
}
}
Does anybody have any suggestions for how I can pass my object from the TableView to the ViewController? I am new to programming and have tried various expressions but nothing seems to work.
The error you're getting has to do with types.
The class NextViewController apparently has a method called -setEntity: that takes an object of type Entity *. The error is because you're trying to give -setEntity: an argument of the wrong type. You're trying to give it an NSInteger (which is a number like 0, 5, -999), but it wants an Entity.
You're on the right track for passing data from the table view to the NextViewController. You just need to do one of the following:
pass an Entity to -setEntity: (does the Entity class perhaps
have a constructor that takes an NSInteger?)
add a method to NextViewController that takes an NSInteger, and call that instead of -setEntity:

UITextView Delegate shouldChangeTextInRange (or any over) doesn't get called

I need to track changes in my UITextView method (actianly for limiting number of lines), but none of UITextViewDelegate methods are being called when editing in UITextView begins. Not even - (void)textViewDidChange:(UITextView *)textView;
I dont know what Im doing wrong
I added UITextViewDelegate method to header file like that:
#interface PirmasViewController : UIViewController <UITextViewDelegate, MFMa......
And I put any methods for tracking changes in my implementation file:
- (void)textViewDidChange:(UITextView *)textView{NSLog(#"something changed");}
- (BOOL)textView:(UITextView *)aTextView shouldChangeTextInRange:(NSRange)aRange replacementText:(NSString*)aText{
NSLog(#"something changed");
return YES;
}`
but no rezults.
I was missing one line of code:
UITextViewFieldName.delegate = self;

Resources